14 * to license@zend.com so we can send you a copy immediately. |
14 * to license@zend.com so we can send you a copy immediately. |
15 * |
15 * |
16 * @category Zend |
16 * @category Zend |
17 * @package Zend_OpenId |
17 * @package Zend_OpenId |
18 * @subpackage Zend_OpenId_Consumer |
18 * @subpackage Zend_OpenId_Consumer |
19 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
19 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) |
20 * @license http://framework.zend.com/license/new-bsd New BSD License |
20 * @license http://framework.zend.com/license/new-bsd New BSD License |
21 * @version $Id: Consumer.php 24593 2012-01-05 20:35:02Z matthew $ |
21 * @version $Id: Consumer.php 24593 2012-01-05 20:35:02Z matthew $ |
22 */ |
22 */ |
23 |
23 |
24 /** |
24 /** |
45 * OpenID consumer implementation |
45 * OpenID consumer implementation |
46 * |
46 * |
47 * @category Zend |
47 * @category Zend |
48 * @package Zend_OpenId |
48 * @package Zend_OpenId |
49 * @subpackage Zend_OpenId_Consumer |
49 * @subpackage Zend_OpenId_Consumer |
50 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
50 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) |
51 * @license http://framework.zend.com/license/new-bsd New BSD License |
51 * @license http://framework.zend.com/license/new-bsd New BSD License |
52 */ |
52 */ |
53 class Zend_OpenId_Consumer |
53 class Zend_OpenId_Consumer |
54 { |
54 { |
|
55 |
|
56 /** |
|
57 * Parameters required for signature |
|
58 */ |
|
59 protected $_signParams = array('op_endpoint', 'return_to', 'response_nonce', 'assoc_handle'); |
55 |
60 |
56 /** |
61 /** |
57 * Reference to an implementation of storage object |
62 * Reference to an implementation of storage object |
58 * |
63 * |
59 * @var Zend_OpenId_Consumer_Storage $_storage |
64 * @var Zend_OpenId_Consumer_Storage $_storage |
257 $this->_setError("Wrong openid.return_to '". |
262 $this->_setError("Wrong openid.return_to '". |
258 $params['openid_return_to']."' != '" . Zend_OpenId::selfUrl() ."'"); |
263 $params['openid_return_to']."' != '" . Zend_OpenId::selfUrl() ."'"); |
259 return false; |
264 return false; |
260 } |
265 } |
261 } |
266 } |
262 |
|
263 if ($version >= 2.0) { |
267 if ($version >= 2.0) { |
264 if (empty($params['openid_response_nonce'])) { |
268 if (empty($params['openid_response_nonce'])) { |
265 $this->_setError("Missing openid.response_nonce"); |
269 $this->_setError("Missing openid.response_nonce"); |
266 return false; |
270 return false; |
267 } |
271 } |
272 } else if (!$this->_storage->isUniqueNonce($params['openid_op_endpoint'], $params['openid_response_nonce'])) { |
276 } else if (!$this->_storage->isUniqueNonce($params['openid_op_endpoint'], $params['openid_response_nonce'])) { |
273 $this->_setError("Duplicate openid.response_nonce"); |
277 $this->_setError("Duplicate openid.response_nonce"); |
274 return false; |
278 return false; |
275 } |
279 } |
276 } |
280 } |
277 |
|
278 |
281 |
279 if (!empty($params['openid_invalidate_handle'])) { |
282 if (!empty($params['openid_invalidate_handle'])) { |
280 if ($this->_storage->getAssociationByHandle( |
283 if ($this->_storage->getAssociationByHandle( |
281 $params['openid_invalidate_handle'], |
284 $params['openid_invalidate_handle'], |
282 $url, |
285 $url, |
291 $params['openid_assoc_handle'], |
294 $params['openid_assoc_handle'], |
292 $url, |
295 $url, |
293 $macFunc, |
296 $macFunc, |
294 $secret, |
297 $secret, |
295 $expires)) { |
298 $expires)) { |
|
299 // Security fix - check the association bewteen op_endpoint and assoc_handle |
|
300 if (isset($params['openid_op_endpoint']) && $url !== $params['openid_op_endpoint']) { |
|
301 $this->_setError("The op_endpoint URI is not the same of URI associated with the assoc_handle"); |
|
302 return false; |
|
303 } |
296 $signed = explode(',', $params['openid_signed']); |
304 $signed = explode(',', $params['openid_signed']); |
|
305 // Check the parameters for the signature |
|
306 // @see https://openid.net/specs/openid-authentication-2_0.html#positive_assertions |
|
307 $toCheck = $this->_signParams; |
|
308 if (isset($params['openid_claimed_id']) && isset($params['openid_identity'])) { |
|
309 $toCheck = array_merge($toCheck, array('claimed_id', 'identity')); |
|
310 } |
|
311 foreach ($toCheck as $param) { |
|
312 if (!in_array($param, $signed, true)) { |
|
313 $this->_setError("The required parameter $param is missing in the signed"); |
|
314 return false; |
|
315 } |
|
316 } |
|
317 |
297 $data = ''; |
318 $data = ''; |
298 foreach ($signed as $key) { |
319 foreach ($signed as $key) { |
299 $data .= $key . ':' . $params['openid_' . strtr($key,'.','_')] . "\n"; |
320 $data .= $key . ':' . $params['openid_' . strtr($key,'.','_')] . "\n"; |
300 } |
321 } |
301 if (base64_decode($params['openid_sig']) == |
322 if (base64_decode($params['openid_sig']) == |
728 $expire)) { |
749 $expire)) { |
729 $id = $realId; |
750 $id = $realId; |
730 return true; |
751 return true; |
731 } |
752 } |
732 |
753 |
733 /* TODO: OpenID 2.0 (7.3) XRI and Yadis discovery */ |
|
734 |
|
735 /* HTML-based discovery */ |
|
736 $response = $this->_httpRequest($id, 'GET', array(), $status); |
754 $response = $this->_httpRequest($id, 'GET', array(), $status); |
737 if ($status != 200 || !is_string($response)) { |
755 if ($status != 200 || !is_string($response)) { |
738 return false; |
756 return false; |
739 } |
757 } |
|
758 |
|
759 /* OpenID 2.0 (7.3) XRI and Yadis discovery */ |
740 if (preg_match( |
760 if (preg_match( |
|
761 '/<meta[^>]*http-equiv=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?X-XRDS-Location[ \t]*[^"\']*\\1[^>]*content=(["\'])([^"\']+)\\2[^>]*\/?>/i', |
|
762 $response, |
|
763 $r)) { |
|
764 $XRDS = $r[3]; |
|
765 $version = 2.0; |
|
766 $response = $this->_httpRequest($XRDS); |
|
767 if (preg_match( |
|
768 '/<URI>([^\t]*)<\/URI>/i', |
|
769 $response, |
|
770 $x)) { |
|
771 $server = $x[1]; |
|
772 // $realId |
|
773 $realId = 'http://specs.openid.net/auth/2.0/identifier_select'; |
|
774 } |
|
775 else { |
|
776 $this->_setError("Unable to get URI for XRDS discovery"); |
|
777 } |
|
778 } |
|
779 |
|
780 /* HTML-based discovery */ |
|
781 else if (preg_match( |
741 '/<link[^>]*rel=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?openid2.provider[ \t]*[^"\']*\\1[^>]*href=(["\'])([^"\']+)\\2[^>]*\/?>/i', |
782 '/<link[^>]*rel=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?openid2.provider[ \t]*[^"\']*\\1[^>]*href=(["\'])([^"\']+)\\2[^>]*\/?>/i', |
742 $response, |
783 $response, |
743 $r)) { |
784 $r)) { |
744 $version = 2.0; |
785 $version = 2.0; |
745 $server = $r[3]; |
786 $server = $r[3]; |