Skip to content

Commit 802278e

Browse files
committed
Update php-saml to 2.10.5. Signature & Digest algorithm support
1 parent 395ef98 commit 802278e

13 files changed

Lines changed: 1016 additions & 172 deletions

onelogin-saml-sso/php/configuration.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
require_once "compatibility.php";
1010
require_once (dirname(__FILE__) . "/lib/Saml2/Constants.php");
11+
require_once (dirname(__FILE__) . "/extlib/xmlseclibs/xmlseclibs.php");
1112

1213

1314
function onelogin_saml_configuration_render() {
@@ -173,6 +174,12 @@ function onelogin_saml_configuration() {
173174

174175
register_setting($option_group, 'onelogin_saml_advanced_settings_sp_privatekey');
175176
add_settings_field('onelogin_saml_advanced_settings_sp_privatekey', __('Service Provider Private Key', 'onelogin-saml-sso'), "plugin_setting_string_onelogin_saml_advanced_settings_sp_privatekey", $option_group, 'advanced_settings');
177+
178+
register_setting($option_group, 'onelogin_saml_advanced_signaturealgorithm');
179+
add_settings_field('onelogin_saml_advanced_signaturealgorithm', __('Signature Algorithm', 'onelogin-saml-sso'), "plugin_setting_select_onelogin_saml_advanced_signaturealgorithm", $option_group, 'advanced_settings');
180+
181+
register_setting($option_group, 'onelogin_saml_advanced_digestalgorithm');
182+
add_settings_field('onelogin_saml_advanced_digestalgorithm', __('Digest Algorithm', 'onelogin-saml-sso'), "plugin_setting_select_onelogin_saml_advanced_digestalgorithm", $option_group, 'advanced_settings');
176183
}
177184

178185
function plugin_setting_string_onelogin_saml_idp_entityid() {
@@ -504,6 +511,45 @@ function plugin_setting_select_onelogin_saml_advanced_requestedauthncontext() {
504511

505512
}
506513

514+
function plugin_setting_select_onelogin_saml_advanced_signaturealgorithm() {
515+
$signaturealgorithm_value = get_option('onelogin_saml_advanced_signaturealgorithm');
516+
$posible_signaturealgorithm_values = array(
517+
'RSA_SHA1' => XMLSecurityKey::RSA_SHA1,
518+
'DSA_SHA1' => XMLSecurityKey::DSA_SHA1,
519+
'RSA_SHA256' => XMLSecurityKey::RSA_SHA256,
520+
'RSA_SHA384' => XMLSecurityKey::RSA_SHA384,
521+
'RSA_SHA512' => XMLSecurityKey::RSA_SHA512
522+
);
523+
524+
echo '<select name="onelogin_saml_advanced_signaturealgorithm" id="onelogin_saml_advanced_signaturealgorithm">';
525+
526+
foreach ($posible_signaturealgorithm_values as $key => $value) {
527+
echo '<option value='.$key.' '.($key == $signaturealgorithm_value ? 'selected="selected"': '').' >'.$value.'</option>';
528+
}
529+
530+
echo '</select>'.
531+
'<p class="description">'.__("Algorithm that will be used on signing process").'</p>';
532+
}
533+
534+
function plugin_setting_select_onelogin_saml_advanced_digestalgorithm() {
535+
$digestalgorithm_value = get_option('onelogin_saml_advanced_digestalgorithm');
536+
$posible_digestalgorithm_values = array(
537+
'SHA1' => XMLSecurityDSig::SHA1,
538+
'SHA256' => XMLSecurityDSig::SHA256,
539+
'SHA384' => XMLSecurityDSig::SHA384,
540+
'SHA512' => XMLSecurityDSig::SHA512
541+
);
542+
543+
echo '<select name="onelogin_saml_advanced_digestalgorithm" id="onelogin_saml_advanced_digestalgorithm">';
544+
545+
foreach ($posible_digestalgorithm_values as $key => $value) {
546+
echo '<option value='.$key.' '.($key == $digestalgorithm_value ? 'selected="selected"': '').' >'.$value.'</option>';
547+
}
548+
549+
echo '</select>'.
550+
'<p class="description">'.__("Algorithm that will be used on digest process").'</p>';
551+
}
552+
507553
function plugin_section_idp_text() {
508554
echo "<p>".__("Set information relating to the IdP that will be connected with our WordPress. You can find these values at the Onelogin's platform inside WordPress on the Single Sign-On tab.", 'onelogin-saml-sso')."</p>";
509555
}

onelogin-saml-sso/php/lib/Saml2/Auth.php

Lines changed: 150 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77
class OneLogin_Saml2_Auth
88
{
9-
109
/**
1110
* Settings data.
1211
*
@@ -28,6 +27,13 @@ class OneLogin_Saml2_Auth
2827
*/
2928
private $_nameid;
3029

30+
/**
31+
* NameID Format
32+
*
33+
* @var string
34+
*/
35+
private $_nameidFormat;
36+
3137
/**
3238
* If user is authenticated.
3339
*
@@ -52,6 +58,28 @@ class OneLogin_Saml2_Auth
5258
*/
5359
private $_sessionExpiration;
5460

61+
/**
62+
* The ID of the last message processed
63+
*
64+
* @var string
65+
*/
66+
private $_lastMessageId;
67+
68+
/**
69+
* The ID of the last assertion processed
70+
*
71+
* @var string
72+
*/
73+
private $_lastAssertionId;
74+
75+
/**
76+
* The NotOnOrAfter value of the valid SubjectConfirmationData
77+
* node (if any) of the last assertion processed
78+
*
79+
* @var DateTime
80+
*/
81+
private $_lastAssertionNotOnOrAfter;
82+
5583
/**
5684
* If any error.
5785
*
@@ -73,6 +101,23 @@ class OneLogin_Saml2_Auth
73101
*/
74102
private $_lastRequestID;
75103

104+
/**
105+
* The most recently-constructed/processed XML SAML request
106+
* (AuthNRequest, LogoutRequest)
107+
*
108+
* @var string
109+
*/
110+
private $_lastRequest;
111+
112+
/**
113+
* The most recently-constructed/processed XML SAML response
114+
* (SAMLResponse, LogoutResponse). If the SAMLResponse was
115+
* encrypted, by default tries to return the decrypted XML
116+
*
117+
* @var string
118+
*/
119+
private $_lastResponse;
120+
76121
/**
77122
* Initializes the SP SAML instance.
78123
*
@@ -103,7 +148,10 @@ public function getSettings()
103148
public function setStrict($value)
104149
{
105150
if (! (is_bool($value))) {
106-
throw new Exception('Invalid value passed to setStrict()');
151+
throw new OneLogin_Saml2_Error(
152+
'Invalid value passed to setStrict()',
153+
OneLogin_Saml2_Error::SETTINGS_INVALID_SYNTAX
154+
);
107155
}
108156

109157
$this->_settings->setStrict($value);
@@ -119,16 +167,22 @@ public function setStrict($value)
119167
public function processResponse($requestId = null)
120168
{
121169
$this->_errors = array();
170+
$this->_errorReason = null;
122171
if (isset($_POST) && isset($_POST['SAMLResponse'])) {
123172
// AuthnResponse -- HTTP_POST Binding
124173
$response = new OneLogin_Saml2_Response($this->_settings, $_POST['SAMLResponse']);
174+
$this->_lastResponse = $response->getXMLDocument();
125175

126176
if ($response->isValid($requestId)) {
127177
$this->_attributes = $response->getAttributes();
128178
$this->_nameid = $response->getNameId();
179+
$this->_nameidFormat = $response->getNameIdFormat();
129180
$this->_authenticated = true;
130181
$this->_sessionIndex = $response->getSessionIndex();
131182
$this->_sessionExpiration = $response->getSessionNotOnOrAfter();
183+
$this->_lastMessageId = $response->getId();
184+
$this->_lastAssertionId = $response->getAssertionId();
185+
$this->_lastAssertionNotOnOrAfter = $response->getAssertionNotOnOrAfter();
132186
} else {
133187
$this->_errors[] = 'invalid_response';
134188
$this->_errorReason = $response->getError();
@@ -155,17 +209,20 @@ public function processResponse($requestId = null)
155209
*
156210
* @throws OneLogin_Saml2_Error
157211
*/
158-
public function processSLO($keepLocalSession = false, $requestId = null, $retrieveParametersFromServer = false, $cbDeleteSession = null, $stay=false)
212+
public function processSLO($keepLocalSession = false, $requestId = null, $retrieveParametersFromServer = false, $cbDeleteSession = null, $stay = false)
159213
{
160214
$this->_errors = array();
215+
$this->_errorReason = null;
161216
if (isset($_GET) && isset($_GET['SAMLResponse'])) {
162217
$logoutResponse = new OneLogin_Saml2_LogoutResponse($this->_settings, $_GET['SAMLResponse']);
218+
$this->_lastResponse = $logoutResponse->getXML();
163219
if (!$logoutResponse->isValid($requestId, $retrieveParametersFromServer)) {
164220
$this->_errors[] = 'invalid_logout_response';
165221
$this->_errorReason = $logoutResponse->getError();
166222
} else if ($logoutResponse->getStatus() !== OneLogin_Saml2_Constants::STATUS_SUCCESS) {
167223
$this->_errors[] = 'logout_not_success';
168224
} else {
225+
$this->_lastMessageId = $logoutResponse->id;
169226
if (!$keepLocalSession) {
170227
if ($cbDeleteSession === null) {
171228
OneLogin_Saml2_Utils::deleteLocalSession();
@@ -176,6 +233,7 @@ public function processSLO($keepLocalSession = false, $requestId = null, $retrie
176233
}
177234
} else if (isset($_GET) && isset($_GET['SAMLRequest'])) {
178235
$logoutRequest = new OneLogin_Saml2_LogoutRequest($this->_settings, $_GET['SAMLRequest']);
236+
$this->_lastRequest = $logoutRequest->getXML();
179237
if (!$logoutRequest->isValid($retrieveParametersFromServer)) {
180238
$this->_errors[] = 'invalid_logout_request';
181239
$this->_errorReason = $logoutRequest->getError();
@@ -188,8 +246,11 @@ public function processSLO($keepLocalSession = false, $requestId = null, $retrie
188246
}
189247
}
190248
$inResponseTo = $logoutRequest->id;
249+
$this->_lastMessageId = $logoutRequest->id;
191250
$responseBuilder = new OneLogin_Saml2_LogoutResponse($this->_settings);
192251
$responseBuilder->build($inResponseTo);
252+
$this->_lastResponse = $responseBuilder->getXML();
253+
193254
$logoutResponse = $responseBuilder->getResponse();
194255

195256
$parameters = array('SAMLResponse' => $logoutResponse);
@@ -265,6 +326,16 @@ public function getNameId()
265326
return $this->_nameid;
266327
}
267328

329+
/**
330+
* Returns the nameID Format
331+
*
332+
* @return string The nameID Format of the assertion
333+
*/
334+
public function getNameIdFormat()
335+
{
336+
return $this->_nameidFormat;
337+
}
338+
268339
/**
269340
* Returns the SessionIndex
270341
*
@@ -335,12 +406,13 @@ public function getAttribute($name)
335406
*
336407
* @return If $stay is True, it return a string with the SLO URL + LogoutRequest + parameters
337408
*/
338-
public function login($returnTo = null, $parameters = array(), $forceAuthn = false, $isPassive = false, $stay=false, $setNameIdPolicy = true)
409+
public function login($returnTo = null, $parameters = array(), $forceAuthn = false, $isPassive = false, $stay = false, $setNameIdPolicy = true)
339410
{
340411
assert('is_array($parameters)');
341412

342413
$authnRequest = new OneLogin_Saml2_AuthnRequest($this->_settings, $forceAuthn, $isPassive, $setNameIdPolicy);
343414

415+
$this->_lastRequest = $authnRequest->getXML();
344416
$this->_lastRequestID = $authnRequest->getId();
345417

346418
$samlRequest = $authnRequest->getRequest();
@@ -369,12 +441,13 @@ public function login($returnTo = null, $parameters = array(), $forceAuthn = fal
369441
* @param string|null $nameId The NameID that will be set in the LogoutRequest.
370442
* @param string|null $sessionIndex The SessionIndex (taken from the SAML Response in the SSO process).
371443
* @param bool $stay True if we want to stay (returns the url string) False to redirect
444+
* @param string|null $nameIdFormat The NameID Format will be set in the LogoutRequest.
372445
*
373446
* @return If $stay is True, it return a string with the SLO URL + LogoutRequest + parameters
374447
*
375448
* @throws OneLogin_Saml2_Error
376449
*/
377-
public function logout($returnTo = null, $parameters = array(), $nameId = null, $sessionIndex = null, $stay=false)
450+
public function logout($returnTo = null, $parameters = array(), $nameId = null, $sessionIndex = null, $stay = false, $nameIdFormat = null)
378451
{
379452
assert('is_array($parameters)');
380453

@@ -389,9 +462,13 @@ public function logout($returnTo = null, $parameters = array(), $nameId = null,
389462
if (empty($nameId) && !empty($this->_nameid)) {
390463
$nameId = $this->_nameid;
391464
}
465+
if (empty($nameIdFormat) && !empty($this->_nameidFormat)) {
466+
$nameIdFormat = $this->_nameidFormat;
467+
}
392468

393-
$logoutRequest = new OneLogin_Saml2_LogoutRequest($this->_settings, null, $nameId, $sessionIndex);
469+
$logoutRequest = new OneLogin_Saml2_LogoutRequest($this->_settings, null, $nameId, $sessionIndex, $nameIdFormat);
394470

471+
$this->_lastRequest = $logoutRequest->getXML();
395472
$this->_lastRequestID = $logoutRequest->id;
396473

397474
$samlRequest = $logoutRequest->getRequest();
@@ -463,10 +540,11 @@ public function getLastRequestID()
463540
*/
464541
public function buildRequestSignature($samlRequest, $relayState, $signAlgorithm = XMLSecurityKey::RSA_SHA1)
465542
{
466-
if (!$this->_settings->checkSPCerts()) {
543+
$key = $this->_settings->getSPkey();
544+
if (empty($key)) {
467545
throw new OneLogin_Saml2_Error(
468-
"Trying to sign the SAML Request but can't load the SP certs",
469-
OneLogin_Saml2_Error::SP_CERTS_NOT_FOUND
546+
"Trying to sign the SAML Request but can't load the SP private key",
547+
OneLogin_Saml2_Error::PRIVATE_KEY_NOT_FOUND
470548
);
471549
}
472550

@@ -507,15 +585,14 @@ public function buildRequestSignature($samlRequest, $relayState, $signAlgorithm
507585
*/
508586
public function buildResponseSignature($samlResponse, $relayState, $signAlgorithm = XMLSecurityKey::RSA_SHA1)
509587
{
510-
if (!$this->_settings->checkSPCerts()) {
588+
$key = $this->_settings->getSPkey();
589+
if (empty($key)) {
511590
throw new OneLogin_Saml2_Error(
512-
"Trying to sign the SAML Response but can't load the SP certs",
513-
OneLogin_Saml2_Error::SP_CERTS_NOT_FOUND
591+
"Trying to sign the SAML Response but can't load the SP private key",
592+
OneLogin_Saml2_Error::PRIVATE_KEY_NOT_FOUND
514593
);
515594
}
516595

517-
$key = $this->_settings->getSPkey();
518-
519596
$objKey = new XMLSecurityKey($signAlgorithm, array('type' => 'private'));
520597
$objKey->loadKey($key, false);
521598

@@ -536,4 +613,63 @@ public function buildResponseSignature($samlResponse, $relayState, $signAlgorith
536613
$signature = $objKey->signData($msg);
537614
return base64_encode($signature);
538615
}
616+
617+
/**
618+
* @return string The ID of the last message processed
619+
*/
620+
public function getLastMessageId()
621+
{
622+
return $this->_lastMessageId;
623+
}
624+
625+
/**
626+
* @return string The ID of the last assertion processed
627+
*/
628+
public function getLastAssertionId()
629+
{
630+
return $this->_lastAssertionId;
631+
}
632+
633+
/**
634+
* @return The NotOnOrAfter value of the valid
635+
* SubjectConfirmationData node (if any)
636+
* of the last assertion processed
637+
*/
638+
public function getLastAssertionNotOnOrAfter()
639+
{
640+
return $this->_lastAssertionNotOnOrAfter;
641+
}
642+
643+
/**
644+
* Returns the most recently-constructed/processed
645+
* XML SAML request (AuthNRequest, LogoutRequest)
646+
*
647+
* @return string The Request XML
648+
*/
649+
public function getLastRequestXML()
650+
{
651+
return $this->_lastRequest;
652+
}
653+
654+
/**
655+
* Returns the most recently-constructed/processed
656+
* XML SAML response (SAMLResponse, LogoutResponse).
657+
* If the SAMLResponse was encrypted, by default tries
658+
* to return the decrypted XML.
659+
*
660+
* @return string The Response XML
661+
*/
662+
public function getLastResponseXML()
663+
{
664+
$response = null;
665+
if (isset($this->_lastResponse)) {
666+
if (is_string($this->_lastResponse)) {
667+
$response = $this->_lastResponse;
668+
} else {
669+
$response = $this->_lastResponse->saveXML();
670+
}
671+
}
672+
673+
return $response;
674+
}
539675
}

0 commit comments

Comments
 (0)