/OpenId/Consumer.php
PHP | 958 lines | 649 code | 74 blank | 235 comment | 185 complexity | 8bb4aa9bef51d6ffdcb0a1e5a0b0c06a MD5 | raw file
- <?php
- /**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_OpenId
- * @subpackage Zend_OpenId_Consumer
- * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Consumer.php 23775 2011-03-01 17:25:24Z ralph $
- */
- /**
- * @see Zend_OpenId
- */
- require_once "Zend/OpenId.php";
- /**
- * @see Zend_OpenId_Extension
- */
- require_once "Zend/OpenId/Extension.php";
- /**
- * @see Zend_OpenId_Consumer_Storage
- */
- require_once "Zend/OpenId/Consumer/Storage.php";
- /**
- * @see Zend_Http_Client
- */
- require_once 'Zend/Http/Client.php';
- /**
- * OpenID consumer implementation
- *
- * @category Zend
- * @package Zend_OpenId
- * @subpackage Zend_OpenId_Consumer
- * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
- class Zend_OpenId_Consumer
- {
- /**
- * Reference to an implementation of storage object
- *
- * @var Zend_OpenId_Consumer_Storage $_storage
- */
- protected $_storage = null;
- /**
- * Enables or disables consumer to use association with server based on
- * Diffie-Hellman key agreement
- *
- * @var Zend_OpenId_Consumer_Storage $_dumbMode
- */
- protected $_dumbMode = false;
- /**
- * Internal cache to prevent unnecessary access to storage
- *
- * @var array $_cache
- */
- protected $_cache = array();
- /**
- * HTTP client to make HTTP requests
- *
- * @var Zend_Http_Client $_httpClient
- */
- private $_httpClient = null;
- /**
- * HTTP session to store climed_id between requests
- *
- * @var Zend_Session_Namespace $_session
- */
- private $_session = null;
- /**
- * Last error message for logi, check or verify failure
- *
- * @var string $_error
- */
- private $_error = '';
- /**
- * Constructs a Zend_OpenId_Consumer object with given $storage.
- * Enables or disables future association with server based on
- * Diffie-Hellman key agreement.
- *
- * @param Zend_OpenId_Consumer_Storage $storage implementation of custom
- * storage object
- * @param bool $dumbMode Enables or disables consumer to use association
- * with server based on Diffie-Hellman key agreement
- */
- public function __construct(Zend_OpenId_Consumer_Storage $storage = null,
- $dumbMode = false)
- {
- if ($storage === null) {
- require_once "Zend/OpenId/Consumer/Storage/File.php";
- $this->_storage = new Zend_OpenId_Consumer_Storage_File();
- } else {
- $this->_storage = $storage;
- }
- $this->_dumbMode = $dumbMode;
- }
- /**
- * Performs check (with possible user interaction) of OpenID identity.
- *
- * This is the first step of OpenID authentication process.
- * On success the function does not return (it does HTTP redirection to
- * server and exits). On failure it returns false.
- *
- * @param string $id OpenID identity
- * @param string $returnTo URL to redirect response from server to
- * @param string $root HTTP URL to identify consumer on server
- * @param mixed $extensions extension object or array of extensions objects
- * @param Zend_Controller_Response_Abstract $response an optional response
- * object to perform HTTP or HTML form redirection
- * @return bool
- */
- public function login($id, $returnTo = null, $root = null, $extensions = null,
- Zend_Controller_Response_Abstract $response = null)
- {
- return $this->_checkId(
- false,
- $id,
- $returnTo,
- $root,
- $extensions,
- $response);
- }
- /**
- * Performs immediate check (without user interaction) of OpenID identity.
- *
- * This is the first step of OpenID authentication process.
- * On success the function does not return (it does HTTP redirection to
- * server and exits). On failure it returns false.
- *
- * @param string $id OpenID identity
- * @param string $returnTo HTTP URL to redirect response from server to
- * @param string $root HTTP URL to identify consumer on server
- * @param mixed $extensions extension object or array of extensions objects
- * @param Zend_Controller_Response_Abstract $response an optional response
- * object to perform HTTP or HTML form redirection
- * @return bool
- */
- public function check($id, $returnTo=null, $root=null, $extensions = null,
- Zend_Controller_Response_Abstract $response = null)
- {
- return $this->_checkId(
- true,
- $id,
- $returnTo,
- $root,
- $extensions,
- $response);
- }
- /**
- * Verifies authentication response from OpenID server.
- *
- * This is the second step of OpenID authentication process.
- * The function returns true on successful authentication and false on
- * failure.
- *
- * @param array $params HTTP query data from OpenID server
- * @param string &$identity this argument is set to end-user's claimed
- * identifier or OpenID provider local identifier.
- * @param mixed $extensions extension object or array of extensions objects
- * @return bool
- */
- public function verify($params, &$identity = "", $extensions = null)
- {
- $this->_setError('');
- $version = 1.1;
- if (isset($params['openid_ns']) &&
- $params['openid_ns'] == Zend_OpenId::NS_2_0) {
- $version = 2.0;
- }
- if (isset($params["openid_claimed_id"])) {
- $identity = $params["openid_claimed_id"];
- } else if (isset($params["openid_identity"])){
- $identity = $params["openid_identity"];
- } else {
- $identity = "";
- }
- if ($version < 2.0 && !isset($params["openid_claimed_id"])) {
- if ($this->_session !== null) {
- if ($this->_session->identity === $identity) {
- $identity = $this->_session->claimed_id;
- }
- } else if (defined('SID')) {
- if (isset($_SESSION["zend_openid"]["identity"]) &&
- isset($_SESSION["zend_openid"]["claimed_id"]) &&
- $_SESSION["zend_openid"]["identity"] === $identity) {
- $identity = $_SESSION["zend_openid"]["claimed_id"];
- }
- } else {
- require_once "Zend/Session/Namespace.php";
- $this->_session = new Zend_Session_Namespace("zend_openid");
- if ($this->_session->identity === $identity) {
- $identity = $this->_session->claimed_id;
- }
- }
- }
- if (empty($params['openid_mode'])) {
- $this->_setError("Missing openid.mode");
- return false;
- }
- if (empty($params['openid_return_to'])) {
- $this->_setError("Missing openid.return_to");
- return false;
- }
- if (empty($params['openid_signed'])) {
- $this->_setError("Missing openid.signed");
- return false;
- }
- if (empty($params['openid_sig'])) {
- $this->_setError("Missing openid.sig");
- return false;
- }
- if ($params['openid_mode'] != 'id_res') {
- $this->_setError("Wrong openid.mode '".$params['openid_mode']."' != 'id_res'");
- return false;
- }
- if (empty($params['openid_assoc_handle'])) {
- $this->_setError("Missing openid.assoc_handle");
- return false;
- }
- if ($params['openid_return_to'] != Zend_OpenId::selfUrl()) {
- /* Ignore query part in openid.return_to */
- $pos = strpos($params['openid_return_to'], '?');
- if ($pos === false ||
- SUBSTR($params['openid_return_to'], 0 , $pos) != Zend_OpenId::selfUrl()) {
- $this->_setError("Wrong openid.return_to '".
- $params['openid_return_to']."' != '" . Zend_OpenId::selfUrl() ."'");
- return false;
- }
- }
- if ($version >= 2.0) {
- if (empty($params['openid_response_nonce'])) {
- $this->_setError("Missing openid.response_nonce");
- return false;
- }
- if (empty($params['openid_op_endpoint'])) {
- $this->_setError("Missing openid.op_endpoint");
- return false;
- /* OpenID 2.0 (11.3) Checking the Nonce */
- } else if (!$this->_storage->isUniqueNonce($params['openid_op_endpoint'], $params['openid_response_nonce'])) {
- $this->_setError("Duplicate openid.response_nonce");
- return false;
- }
- }
- if (!empty($params['openid_invalidate_handle'])) {
- if ($this->_storage->getAssociationByHandle(
- $params['openid_invalidate_handle'],
- $url,
- $macFunc,
- $secret,
- $expires)) {
- $this->_storage->delAssociation($url);
- }
- }
- if ($this->_storage->getAssociationByHandle(
- $params['openid_assoc_handle'],
- $url,
- $macFunc,
- $secret,
- $expires)) {
- $signed = explode(',', $params['openid_signed']);
- $data = '';
- foreach ($signed as $key) {
- $data .= $key . ':' . $params['openid_' . strtr($key,'.','_')] . "\n";
- }
- if (base64_decode($params['openid_sig']) ==
- Zend_OpenId::hashHmac($macFunc, $data, $secret)) {
- if (!Zend_OpenId_Extension::forAll($extensions, 'parseResponse', $params)) {
- $this->_setError("Extension::parseResponse failure");
- return false;
- }
- /* OpenID 2.0 (11.2) Verifying Discovered Information */
- if (isset($params['openid_claimed_id'])) {
- $id = $params['openid_claimed_id'];
- if (!Zend_OpenId::normalize($id)) {
- $this->_setError("Normalization failed");
- return false;
- } else if (!$this->_discovery($id, $discovered_server, $discovered_version)) {
- $this->_setError("Discovery failed: " . $this->getError());
- return false;
- } else if ((!empty($params['openid_identity']) &&
- $params["openid_identity"] != $id) ||
- (!empty($params['openid_op_endpoint']) &&
- $params['openid_op_endpoint'] != $discovered_server) ||
- $discovered_version != $version) {
- $this->_setError("Discovery information verification failed");
- return false;
- }
- }
- return true;
- }
- $this->_storage->delAssociation($url);
- $this->_setError("Signature check failed");
- return false;
- }
- else
- {
- /* Use dumb mode */
- if (isset($params['openid_claimed_id'])) {
- $id = $params['openid_claimed_id'];
- } else if (isset($params['openid_identity'])) {
- $id = $params['openid_identity'];
- } else {
- $this->_setError("Missing openid.claimed_id and openid.identity");
- return false;
- }
- if (!Zend_OpenId::normalize($id)) {
- $this->_setError("Normalization failed");
- return false;
- } else if (!$this->_discovery($id, $server, $discovered_version)) {
- $this->_setError("Discovery failed: " . $this->getError());
- return false;
- }
- /* OpenID 2.0 (11.2) Verifying Discovered Information */
- if ((isset($params['openid_identity']) &&
- $params["openid_identity"] != $id) ||
- (isset($params['openid_op_endpoint']) &&
- $params['openid_op_endpoint'] != $server) ||
- $discovered_version != $version) {
- $this->_setError("Discovery information verification failed");
- return false;
- }
- $params2 = array();
- foreach ($params as $key => $val) {
- if (strpos($key, 'openid_ns_') === 0) {
- $key = 'openid.ns.' . substr($key, strlen('openid_ns_'));
- } else if (strpos($key, 'openid_sreg_') === 0) {
- $key = 'openid.sreg.' . substr($key, strlen('openid_sreg_'));
- } else if (strpos($key, 'openid_') === 0) {
- $key = 'openid.' . substr($key, strlen('openid_'));
- }
- $params2[$key] = $val;
- }
- $params2['openid.mode'] = 'check_authentication';
- $ret = $this->_httpRequest($server, 'POST', $params2, $status);
- if ($status != 200) {
- $this->_setError("'Dumb' signature verification HTTP request failed");
- return false;
- }
- $r = array();
- if (is_string($ret)) {
- foreach(explode("\n", $ret) as $line) {
- $line = trim($line);
- if (!empty($line)) {
- $x = explode(':', $line, 2);
- if (is_array($x) && count($x) == 2) {
- list($key, $value) = $x;
- $r[trim($key)] = trim($value);
- }
- }
- }
- }
- $ret = $r;
- if (!empty($ret['invalidate_handle'])) {
- if ($this->_storage->getAssociationByHandle(
- $ret['invalidate_handle'],
- $url,
- $macFunc,
- $secret,
- $expires)) {
- $this->_storage->delAssociation($url);
- }
- }
- if (isset($ret['is_valid']) && $ret['is_valid'] == 'true') {
- if (!Zend_OpenId_Extension::forAll($extensions, 'parseResponse', $params)) {
- $this->_setError("Extension::parseResponse failure");
- return false;
- }
- return true;
- }
- $this->_setError("'Dumb' signature verification failed");
- return false;
- }
- }
- /**
- * Store assiciation in internal chace and external storage
- *
- * @param string $url OpenID server url
- * @param string $handle association handle
- * @param string $macFunc HMAC function (sha1 or sha256)
- * @param string $secret shared secret
- * @param integer $expires expiration UNIX time
- * @return void
- */
- protected function _addAssociation($url, $handle, $macFunc, $secret, $expires)
- {
- $this->_cache[$url] = array($handle, $macFunc, $secret, $expires);
- return $this->_storage->addAssociation(
- $url,
- $handle,
- $macFunc,
- $secret,
- $expires);
- }
- /**
- * Retrive assiciation information for given $url from internal cahce or
- * external storage
- *
- * @param string $url OpenID server url
- * @param string &$handle association handle
- * @param string &$macFunc HMAC function (sha1 or sha256)
- * @param string &$secret shared secret
- * @param integer &$expires expiration UNIX time
- * @return void
- */
- protected function _getAssociation($url, &$handle, &$macFunc, &$secret, &$expires)
- {
- if (isset($this->_cache[$url])) {
- $handle = $this->_cache[$url][0];
- $macFunc = $this->_cache[$url][1];
- $secret = $this->_cache[$url][2];
- $expires = $this->_cache[$url][3];
- return true;
- }
- if ($this->_storage->getAssociation(
- $url,
- $handle,
- $macFunc,
- $secret,
- $expires)) {
- $this->_cache[$url] = array($handle, $macFunc, $secret, $expires);
- return true;
- }
- return false;
- }
- /**
- * Performs HTTP request to given $url using given HTTP $method.
- * Send additinal query specified by variable/value array,
- * On success returns HTTP response without headers, false on failure.
- *
- * @param string $url OpenID server url
- * @param string $method HTTP request method 'GET' or 'POST'
- * @param array $params additional qwery parameters to be passed with
- * @param int &$staus HTTP status code
- * request
- * @return mixed
- */
- protected function _httpRequest($url, $method = 'GET', array $params = array(), &$status = null)
- {
- $client = $this->_httpClient;
- if ($client === null) {
- $client = new Zend_Http_Client(
- $url,
- array(
- 'maxredirects' => 4,
- 'timeout' => 15,
- 'useragent' => 'Zend_OpenId'
- )
- );
- } else {
- $client->setUri($url);
- }
- $client->resetParameters();
- if ($method == 'POST') {
- $client->setMethod(Zend_Http_Client::POST);
- $client->setParameterPost($params);
- } else {
- $client->setMethod(Zend_Http_Client::GET);
- $client->setParameterGet($params);
- }
- try {
- $response = $client->request();
- } catch (Exception $e) {
- $this->_setError('HTTP Request failed: ' . $e->getMessage());
- return false;
- }
- $status = $response->getStatus();
- $body = $response->getBody();
- if ($status == 200 || ($status == 400 && !empty($body))) {
- return $body;
- }else{
- $this->_setError('Bad HTTP response');
- return false;
- }
- }
- /**
- * Create (or reuse existing) association between OpenID consumer and
- * OpenID server based on Diffie-Hellman key agreement. Returns true
- * on success and false on failure.
- *
- * @param string $url OpenID server url
- * @param float $version OpenID protocol version
- * @param string $priv_key for testing only
- * @return bool
- */
- protected function _associate($url, $version, $priv_key=null)
- {
- /* Check if we already have association in chace or storage */
- if ($this->_getAssociation(
- $url,
- $handle,
- $macFunc,
- $secret,
- $expires)) {
- return true;
- }
- if ($this->_dumbMode) {
- /* Use dumb mode */
- return true;
- }
- $params = array();
- if ($version >= 2.0) {
- $params = array(
- 'openid.ns' => Zend_OpenId::NS_2_0,
- 'openid.mode' => 'associate',
- 'openid.assoc_type' => 'HMAC-SHA256',
- 'openid.session_type' => 'DH-SHA256',
- );
- } else {
- $params = array(
- 'openid.mode' => 'associate',
- 'openid.assoc_type' => 'HMAC-SHA1',
- 'openid.session_type' => 'DH-SHA1',
- );
- }
- $dh = Zend_OpenId::createDhKey(pack('H*', Zend_OpenId::DH_P),
- pack('H*', Zend_OpenId::DH_G),
- $priv_key);
- $dh_details = Zend_OpenId::getDhKeyDetails($dh);
- $params['openid.dh_modulus'] = base64_encode(
- Zend_OpenId::btwoc($dh_details['p']));
- $params['openid.dh_gen'] = base64_encode(
- Zend_OpenId::btwoc($dh_details['g']));
- $params['openid.dh_consumer_public'] = base64_encode(
- Zend_OpenId::btwoc($dh_details['pub_key']));
- while(1) {
- $ret = $this->_httpRequest($url, 'POST', $params, $status);
- if ($ret === false) {
- $this->_setError("HTTP request failed");
- return false;
- }
- $r = array();
- $bad_response = false;
- foreach(explode("\n", $ret) as $line) {
- $line = trim($line);
- if (!empty($line)) {
- $x = explode(':', $line, 2);
- if (is_array($x) && count($x) == 2) {
- list($key, $value) = $x;
- $r[trim($key)] = trim($value);
- } else {
- $bad_response = true;
- }
- }
- }
- if ($bad_response && strpos($ret, 'Unknown session type') !== false) {
- $r['error_code'] = 'unsupported-type';
- }
- $ret = $r;
- if (isset($ret['error_code']) &&
- $ret['error_code'] == 'unsupported-type') {
- if ($params['openid.session_type'] == 'DH-SHA256') {
- $params['openid.session_type'] = 'DH-SHA1';
- $params['openid.assoc_type'] = 'HMAC-SHA1';
- } else if ($params['openid.session_type'] == 'DH-SHA1') {
- $params['openid.session_type'] = 'no-encryption';
- } else {
- $this->_setError("The OpenID service responded with: " . $ret['error_code']);
- return false;
- }
- } else {
- break;
- }
- }
- if ($status != 200) {
- $this->_setError("The server responded with status code: " . $status);
- return false;
- }
- if ($version >= 2.0 &&
- isset($ret['ns']) &&
- $ret['ns'] != Zend_OpenId::NS_2_0) {
- $this->_setError("Wrong namespace definition in the server response");
- return false;
- }
- if (!isset($ret['assoc_handle']) ||
- !isset($ret['expires_in']) ||
- !isset($ret['assoc_type']) ||
- $params['openid.assoc_type'] != $ret['assoc_type']) {
- if ($params['openid.assoc_type'] != $ret['assoc_type']) {
- $this->_setError("The returned assoc_type differed from the supplied openid.assoc_type");
- } else {
- $this->_setError("Missing required data from provider (assoc_handle, expires_in, assoc_type are required)");
- }
- return false;
- }
- $handle = $ret['assoc_handle'];
- $expiresIn = $ret['expires_in'];
- if ($ret['assoc_type'] == 'HMAC-SHA1') {
- $macFunc = 'sha1';
- } else if ($ret['assoc_type'] == 'HMAC-SHA256' &&
- $version >= 2.0) {
- $macFunc = 'sha256';
- } else {
- $this->_setError("Unsupported assoc_type");
- return false;
- }
- if ((empty($ret['session_type']) ||
- ($version >= 2.0 && $ret['session_type'] == 'no-encryption')) &&
- isset($ret['mac_key'])) {
- $secret = base64_decode($ret['mac_key']);
- } else if (isset($ret['session_type']) &&
- $ret['session_type'] == 'DH-SHA1' &&
- !empty($ret['dh_server_public']) &&
- !empty($ret['enc_mac_key'])) {
- $dhFunc = 'sha1';
- } else if (isset($ret['session_type']) &&
- $ret['session_type'] == 'DH-SHA256' &&
- $version >= 2.0 &&
- !empty($ret['dh_server_public']) &&
- !empty($ret['enc_mac_key'])) {
- $dhFunc = 'sha256';
- } else {
- $this->_setError("Unsupported session_type");
- return false;
- }
- if (isset($dhFunc)) {
- $serverPub = base64_decode($ret['dh_server_public']);
- $dhSec = Zend_OpenId::computeDhSecret($serverPub, $dh);
- if ($dhSec === false) {
- $this->_setError("DH secret comutation failed");
- return false;
- }
- $sec = Zend_OpenId::digest($dhFunc, $dhSec);
- if ($sec === false) {
- $this->_setError("Could not create digest");
- return false;
- }
- $secret = $sec ^ base64_decode($ret['enc_mac_key']);
- }
- if ($macFunc == 'sha1') {
- if (Zend_OpenId::strlen($secret) != 20) {
- $this->_setError("The length of the sha1 secret must be 20");
- return false;
- }
- } else if ($macFunc == 'sha256') {
- if (Zend_OpenId::strlen($secret) != 32) {
- $this->_setError("The length of the sha256 secret must be 32");
- return false;
- }
- }
- $this->_addAssociation(
- $url,
- $handle,
- $macFunc,
- $secret,
- time() + $expiresIn);
- return true;
- }
- /**
- * Performs discovery of identity and finds OpenID URL, OpenID server URL
- * and OpenID protocol version. Returns true on succees and false on
- * failure.
- *
- * @param string &$id OpenID identity URL
- * @param string &$server OpenID server URL
- * @param float &$version OpenID protocol version
- * @return bool
- * @todo OpenID 2.0 (7.3) XRI and Yadis discovery
- */
- protected function _discovery(&$id, &$server, &$version)
- {
- $realId = $id;
- if ($this->_storage->getDiscoveryInfo(
- $id,
- $realId,
- $server,
- $version,
- $expire)) {
- $id = $realId;
- return true;
- }
- /* TODO: OpenID 2.0 (7.3) XRI and Yadis discovery */
- /* HTML-based discovery */
- $response = $this->_httpRequest($id, 'GET', array(), $status);
- if ($status != 200 || !is_string($response)) {
- return false;
- }
- if (preg_match(
- '/<link[^>]*rel=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?openid2.provider[ \t]*[^"\']*\\1[^>]*href=(["\'])([^"\']+)\\2[^>]*\/?>/i',
- $response,
- $r)) {
- $version = 2.0;
- $server = $r[3];
- } else if (preg_match(
- '/<link[^>]*href=(["\'])([^"\']+)\\1[^>]*rel=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?openid2.provider[ \t]*[^"\']*\\3[^>]*\/?>/i',
- $response,
- $r)) {
- $version = 2.0;
- $server = $r[2];
- } else if (preg_match(
- '/<link[^>]*rel=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?openid.server[ \t]*[^"\']*\\1[^>]*href=(["\'])([^"\']+)\\2[^>]*\/?>/i',
- $response,
- $r)) {
- $version = 1.1;
- $server = $r[3];
- } else if (preg_match(
- '/<link[^>]*href=(["\'])([^"\']+)\\1[^>]*rel=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?openid.server[ \t]*[^"\']*\\3[^>]*\/?>/i',
- $response,
- $r)) {
- $version = 1.1;
- $server = $r[2];
- } else {
- return false;
- }
- if ($version >= 2.0) {
- if (preg_match(
- '/<link[^>]*rel=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?openid2.local_id[ \t]*[^"\']*\\1[^>]*href=(["\'])([^"\']+)\\2[^>]*\/?>/i',
- $response,
- $r)) {
- $realId = $r[3];
- } else if (preg_match(
- '/<link[^>]*href=(["\'])([^"\']+)\\1[^>]*rel=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?openid2.local_id[ \t]*[^"\']*\\3[^>]*\/?>/i',
- $response,
- $r)) {
- $realId = $r[2];
- }
- } else {
- if (preg_match(
- '/<link[^>]*rel=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?openid.delegate[ \t]*[^"\']*\\1[^>]*href=(["\'])([^"\']+)\\2[^>]*\/?>/i',
- $response,
- $r)) {
- $realId = $r[3];
- } else if (preg_match(
- '/<link[^>]*href=(["\'])([^"\']+)\\1[^>]*rel=(["\'])[ \t]*(?:[^ \t"\']+[ \t]+)*?openid.delegate[ \t]*[^"\']*\\3[^>]*\/?>/i',
- $response,
- $r)) {
- $realId = $r[2];
- }
- }
- $expire = time() + 60 * 60;
- $this->_storage->addDiscoveryInfo($id, $realId, $server, $version, $expire);
- $id = $realId;
- return true;
- }
- /**
- * Performs check of OpenID identity.
- *
- * This is the first step of OpenID authentication process.
- * On success the function does not return (it does HTTP redirection to
- * server and exits). On failure it returns false.
- *
- * @param bool $immediate enables or disables interaction with user
- * @param string $id OpenID identity
- * @param string $returnTo HTTP URL to redirect response from server to
- * @param string $root HTTP URL to identify consumer on server
- * @param mixed $extensions extension object or array of extensions objects
- * @param Zend_Controller_Response_Abstract $response an optional response
- * object to perform HTTP or HTML form redirection
- * @return bool
- */
- protected function _checkId($immediate, $id, $returnTo=null, $root=null,
- $extensions=null, Zend_Controller_Response_Abstract $response = null)
- {
- $this->_setError('');
- if (!Zend_OpenId::normalize($id)) {
- $this->_setError("Normalisation failed");
- return false;
- }
- $claimedId = $id;
- if (!$this->_discovery($id, $server, $version)) {
- $this->_setError("Discovery failed: " . $this->getError());
- return false;
- }
- if (!$this->_associate($server, $version)) {
- $this->_setError("Association failed: " . $this->getError());
- return false;
- }
- if (!$this->_getAssociation(
- $server,
- $handle,
- $macFunc,
- $secret,
- $expires)) {
- /* Use dumb mode */
- unset($handle);
- unset($macFunc);
- unset($secret);
- unset($expires);
- }
- $params = array();
- if ($version >= 2.0) {
- $params['openid.ns'] = Zend_OpenId::NS_2_0;
- }
- $params['openid.mode'] = $immediate ?
- 'checkid_immediate' : 'checkid_setup';
- $params['openid.identity'] = $id;
- $params['openid.claimed_id'] = $claimedId;
- if ($version <= 2.0) {
- if ($this->_session !== null) {
- $this->_session->identity = $id;
- $this->_session->claimed_id = $claimedId;
- } else if (defined('SID')) {
- $_SESSION["zend_openid"] = array(
- "identity" => $id,
- "claimed_id" => $claimedId);
- } else {
- require_once "Zend/Session/Namespace.php";
- $this->_session = new Zend_Session_Namespace("zend_openid");
- $this->_session->identity = $id;
- $this->_session->claimed_id = $claimedId;
- }
- }
- if (isset($handle)) {
- $params['openid.assoc_handle'] = $handle;
- }
- $params['openid.return_to'] = Zend_OpenId::absoluteUrl($returnTo);
- if (empty($root)) {
- $root = Zend_OpenId::selfUrl();
- if ($root[strlen($root)-1] != '/') {
- $root = dirname($root);
- }
- }
- if ($version >= 2.0) {
- $params['openid.realm'] = $root;
- } else {
- $params['openid.trust_root'] = $root;
- }
- if (!Zend_OpenId_Extension::forAll($extensions, 'prepareRequest', $params)) {
- $this->_setError("Extension::prepareRequest failure");
- return false;
- }
- Zend_OpenId::redirect($server, $params, $response);
- return true;
- }
- /**
- * Sets HTTP client object to make HTTP requests
- *
- * @param Zend_Http_Client $client HTTP client object to be used
- */
- public function setHttpClient($client) {
- $this->_httpClient = $client;
- }
- /**
- * Returns HTTP client object that will be used to make HTTP requests
- *
- * @return Zend_Http_Client
- */
- public function getHttpClient() {
- return $this->_httpClient;
- }
- /**
- * Sets session object to store climed_id
- *
- * @param Zend_Session_Namespace $session HTTP client object to be used
- */
- public function setSession(Zend_Session_Namespace $session) {
- $this->_session = $session;
- }
- /**
- * Returns session object that is used to store climed_id
- *
- * @return Zend_Session_Namespace
- */
- public function getSession() {
- return $this->_session;
- }
- /**
- * Saves error message
- *
- * @param string $message error message
- */
- protected function _setError($message)
- {
- $this->_error = $message;
- }
- /**
- * Returns error message that explains failure of login, check or verify
- *
- * @return string
- */
- public function getError()
- {
- return $this->_error;
- }
- }