summaryrefslogtreecommitdiff
path: root/applications/core/lib/Zend/OpenId
diff options
Diffstat (limited to 'applications/core/lib/Zend/OpenId')
-rw-r--r--applications/core/lib/Zend/OpenId/Consumer.php958
-rw-r--r--applications/core/lib/Zend/OpenId/Consumer/Storage.php132
-rw-r--r--applications/core/lib/Zend/OpenId/Consumer/Storage/File.php460
-rw-r--r--applications/core/lib/Zend/OpenId/Exception.php58
-rw-r--r--applications/core/lib/Zend/OpenId/Extension.php137
-rw-r--r--applications/core/lib/Zend/OpenId/Extension/Sreg.php300
-rw-r--r--applications/core/lib/Zend/OpenId/Provider.php781
-rw-r--r--applications/core/lib/Zend/OpenId/Provider/Storage.php106
-rw-r--r--applications/core/lib/Zend/OpenId/Provider/Storage/File.php397
-rw-r--r--applications/core/lib/Zend/OpenId/Provider/User.php57
-rw-r--r--applications/core/lib/Zend/OpenId/Provider/User/Session.php104
11 files changed, 3490 insertions, 0 deletions
diff --git a/applications/core/lib/Zend/OpenId/Consumer.php b/applications/core/lib/Zend/OpenId/Consumer.php
new file mode 100644
index 0000000..7b4d6dc
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Consumer.php
@@ -0,0 +1,958 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Consumer
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Consumer.php 14674 2009-04-05 13:58:39Z [email protected] $
+ */
+
+/**
+ * @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-2008 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;
+ }
+
+}
diff --git a/applications/core/lib/Zend/OpenId/Consumer/Storage.php b/applications/core/lib/Zend/OpenId/Consumer/Storage.php
new file mode 100644
index 0000000..68e4ed0
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Consumer/Storage.php
@@ -0,0 +1,132 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Consumer
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Storage.php 9239 2008-04-18 12:09:31Z dmitry $
+ */
+
+/**
+ * Abstract class to implement external storage for OpenID consumer
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Consumer
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_OpenId_Consumer_Storage
+{
+
+ /**
+ * Stores information about association identified by $url/$handle
+ *
+ * @param string $url OpenID server URL
+ * @param string $handle assiciation handle
+ * @param string $macFunc HMAC function (sha1 or sha256)
+ * @param string $secret shared secret
+ * @param long $expires expiration UNIX time
+ * @return void
+ */
+ abstract public function addAssociation($url, $handle, $macFunc, $secret, $expires);
+
+ /**
+ * Gets information about association identified by $url
+ * Returns true if given association found and not expired and false
+ * otherwise
+ *
+ * @param string $url OpenID server URL
+ * @param string &$handle assiciation handle
+ * @param string &$macFunc HMAC function (sha1 or sha256)
+ * @param string &$secret shared secret
+ * @param long &$expires expiration UNIX time
+ * @return bool
+ */
+ abstract public function getAssociation($url, &$handle, &$macFunc, &$secret, &$expires);
+
+ /**
+ * Gets information about association identified by $handle
+ * Returns true if given association found and not expired and false
+ * othverwise
+ *
+ * @param string $handle assiciation handle
+ * @param string &$url OpenID server URL
+ * @param string &$macFunc HMAC function (sha1 or sha256)
+ * @param string &$secret shared secret
+ * @param long &$expires expiration UNIX time
+ * @return bool
+ */
+ abstract public function getAssociationByHandle($handle, &$url, &$macFunc, &$secret, &$expires);
+
+ /**
+ * Deletes association identified by $url
+ *
+ * @param string $url OpenID server URL
+ * @return void
+ */
+ abstract public function delAssociation($url);
+
+ /**
+ * Stores information discovered from identity $id
+ *
+ * @param string $id identity
+ * @param string $realId discovered real identity URL
+ * @param string $server discovered OpenID server URL
+ * @param float $version discovered OpenID protocol version
+ * @param long $expires expiration UNIX time
+ * @return void
+ */
+ abstract public function addDiscoveryInfo($id, $realId, $server, $version, $expires);
+
+ /**
+ * Gets information discovered from identity $id
+ * Returns true if such information exists and false otherwise
+ *
+ * @param string $id identity
+ * @param string &$realId discovered real identity URL
+ * @param string &$server discovered OpenID server URL
+ * @param float &$version discovered OpenID protocol version
+ * @param long &$expires expiration UNIX time
+ * @return bool
+ */
+ abstract public function getDiscoveryInfo($id, &$realId, &$server, &$version, &$expires);
+
+ /**
+ * Removes cached information discovered from identity $id
+ *
+ * @param string $id identity
+ * @return bool
+ */
+ abstract public function delDiscoveryInfo($id);
+
+ /**
+ * The function checks the uniqueness of openid.response_nonce
+ *
+ * @param string $provider openid.openid_op_endpoint field from authentication response
+ * @param string $nonce openid.response_nonce field from authentication response
+ * @return bool
+ */
+ abstract public function isUniqueNonce($provider, $nonce);
+
+ /**
+ * Removes data from the uniqueness database that is older then given date
+ *
+ * @param string $date Date of expired data
+ */
+ abstract public function purgeNonces($date=null);
+}
diff --git a/applications/core/lib/Zend/OpenId/Consumer/Storage/File.php b/applications/core/lib/Zend/OpenId/Consumer/Storage/File.php
new file mode 100644
index 0000000..c75dea9
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Consumer/Storage/File.php
@@ -0,0 +1,460 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Consumer
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: File.php 13522 2009-01-06 16:35:55Z thomas $
+ */
+
+/**
+ * @see Zend_OpenId_Consumer_Storage
+ */
+require_once "Zend/OpenId/Consumer/Storage.php";
+
+/**
+ * External storage implemmentation using serialized files
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Consumer
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_OpenId_Consumer_Storage_File extends Zend_OpenId_Consumer_Storage
+{
+
+ /**
+ * Directory name to store data files in
+ *
+ * @var string $_dir
+ */
+ private $_dir;
+
+ /**
+ * Constructs storage object and creates storage directory
+ *
+ * @param string $dir directory name to store data files in
+ * @throws Zend_OpenId_Exception
+ */
+ public function __construct($dir = null)
+ {
+ if ($dir === null) {
+ $tmp = getenv('TMP');
+ if (empty($tmp)) {
+ $tmp = getenv('TEMP');
+ if (empty($tmp)) {
+ $tmp = "/tmp";
+ }
+ }
+ $user = get_current_user();
+ if (is_string($user) && !empty($user)) {
+ $tmp .= '/' . $user;
+ }
+ $dir = $tmp . '/openid/consumer';
+ }
+ $this->_dir = $dir;
+ if (!is_dir($this->_dir)) {
+ if (!@mkdir($this->_dir, 0700, 1)) {
+ /**
+ * @see Zend_OpenId_Exception
+ */
+ require_once 'Zend/OpenId/Exception.php';
+ throw new Zend_OpenId_Exception(
+ 'Cannot access storage directory ' . $dir,
+ Zend_OpenId_Exception::ERROR_STORAGE);
+ }
+ }
+ if (($f = fopen($this->_dir.'/assoc.lock', 'w+')) === null) {
+ /**
+ * @see Zend_OpenId_Exception
+ */
+ require_once 'Zend/OpenId/Exception.php';
+ throw new Zend_OpenId_Exception(
+ 'Cannot create a lock file in the directory ' . $dir,
+ Zend_OpenId_Exception::ERROR_STORAGE);
+ }
+ fclose($f);
+ if (($f = fopen($this->_dir.'/discovery.lock', 'w+')) === null) {
+ /**
+ * @see Zend_OpenId_Exception
+ */
+ require_once 'Zend/OpenId/Exception.php';
+ throw new Zend_OpenId_Exception(
+ 'Cannot create a lock file in the directory ' . $dir,
+ Zend_OpenId_Exception::ERROR_STORAGE);
+ }
+ fclose($f);
+ if (($f = fopen($this->_dir.'/nonce.lock', 'w+')) === null) {
+ /**
+ * @see Zend_OpenId_Exception
+ */
+ require_once 'Zend/OpenId/Exception.php';
+ throw new Zend_OpenId_Exception(
+ 'Cannot create a lock file in the directory ' . $dir,
+ Zend_OpenId_Exception::ERROR_STORAGE);
+ }
+ fclose($f);
+ }
+
+ /**
+ * Stores information about association identified by $url/$handle
+ *
+ * @param string $url OpenID server URL
+ * @param string $handle assiciation handle
+ * @param string $macFunc HMAC function (sha1 or sha256)
+ * @param string $secret shared secret
+ * @param long $expires expiration UNIX time
+ * @return bool
+ */
+ public function addAssociation($url, $handle, $macFunc, $secret, $expires)
+ {
+ $name1 = $this->_dir . '/assoc_url_' . md5($url);
+ $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
+ $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name1, 'w+');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $data = serialize(array($url, $handle, $macFunc, $secret, $expires));
+ fwrite($f, $data);
+ if (function_exists('symlink')) {
+ @unlink($name2);
+ if (symlink($name1, $name2)) {
+ fclose($f);
+ fclose($lock);
+ return true;
+ }
+ }
+ $f2 = @fopen($name2, 'w+');
+ if ($f2) {
+ fwrite($f2, $data);
+ fclose($f2);
+ @unlink($name1);
+ $ret = true;
+ } else {
+ $ret = false;
+ }
+ fclose($f);
+ fclose($lock);
+ return $ret;
+ }
+
+ /**
+ * Gets information about association identified by $url
+ * Returns true if given association found and not expired and false
+ * otherwise
+ *
+ * @param string $url OpenID server URL
+ * @param string &$handle assiciation handle
+ * @param string &$macFunc HMAC function (sha1 or sha256)
+ * @param string &$secret shared secret
+ * @param long &$expires expiration UNIX time
+ * @return bool
+ */
+ public function getAssociation($url, &$handle, &$macFunc, &$secret, &$expires)
+ {
+ $name1 = $this->_dir . '/assoc_url_' . md5($url);
+ $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name1, 'r');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $ret = false;
+ $data = stream_get_contents($f);
+ if (!empty($data)) {
+ list($storedUrl, $handle, $macFunc, $secret, $expires) = unserialize($data);
+ if ($url === $storedUrl && $expires > time()) {
+ $ret = true;
+ } else {
+ $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
+ fclose($f);
+ @unlink($name2);
+ @unlink($name1);
+ fclose($lock);
+ return false;
+ }
+ }
+ fclose($f);
+ fclose($lock);
+ return $ret;
+ }
+
+ /**
+ * Gets information about association identified by $handle
+ * Returns true if given association found and not expired and false
+ * otherwise
+ *
+ * @param string $handle assiciation handle
+ * @param string &$url OpenID server URL
+ * @param string &$macFunc HMAC function (sha1 or sha256)
+ * @param string &$secret shared secret
+ * @param long &$expires expiration UNIX time
+ * @return bool
+ */
+ public function getAssociationByHandle($handle, &$url, &$macFunc, &$secret, &$expires)
+ {
+ $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
+ $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name2, 'r');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $ret = false;
+ $data = stream_get_contents($f);
+ if (!empty($data)) {
+ list($url, $storedHandle, $macFunc, $secret, $expires) = unserialize($data);
+ if ($handle === $storedHandle && $expires > time()) {
+ $ret = true;
+ } else {
+ fclose($f);
+ @unlink($name2);
+ $name1 = $this->_dir . '/assoc_url_' . md5($url);
+ @unlink($name1);
+ fclose($lock);
+ return false;
+ }
+ }
+ fclose($f);
+ fclose($lock);
+ return $ret;
+ }
+
+ /**
+ * Deletes association identified by $url
+ *
+ * @param string $url OpenID server URL
+ * @return bool
+ */
+ public function delAssociation($url)
+ {
+ $name1 = $this->_dir . '/assoc_url_' . md5($url);
+ $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name1, 'r');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $data = stream_get_contents($f);
+ if (!empty($data)) {
+ list($storedUrl, $handle, $macFunc, $secret, $expires) = unserialize($data);
+ if ($url === $storedUrl) {
+ $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
+ fclose($f);
+ @unlink($name2);
+ @unlink($name1);
+ fclose($lock);
+ return true;
+ }
+ }
+ fclose($f);
+ fclose($lock);
+ return true;
+ }
+
+ /**
+ * Stores information discovered from identity $id
+ *
+ * @param string $id identity
+ * @param string $realId discovered real identity URL
+ * @param string $server discovered OpenID server URL
+ * @param float $version discovered OpenID protocol version
+ * @param long $expires expiration UNIX time
+ * @return bool
+ */
+ public function addDiscoveryInfo($id, $realId, $server, $version, $expires)
+ {
+ $name = $this->_dir . '/discovery_' . md5($id);
+ $lock = @fopen($this->_dir . '/discovery.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name, 'w+');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $data = serialize(array($id, $realId, $server, $version, $expires));
+ fwrite($f, $data);
+ fclose($f);
+ fclose($lock);
+ return true;
+ }
+
+ /**
+ * Gets information discovered from identity $id
+ * Returns true if such information exists and false otherwise
+ *
+ * @param string $id identity
+ * @param string &$realId discovered real identity URL
+ * @param string &$server discovered OpenID server URL
+ * @param float &$version discovered OpenID protocol version
+ * @param long &$expires expiration UNIX time
+ * @return bool
+ */
+ public function getDiscoveryInfo($id, &$realId, &$server, &$version, &$expires)
+ {
+ $name = $this->_dir . '/discovery_' . md5($id);
+ $lock = @fopen($this->_dir . '/discovery.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name, 'r');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $ret = false;
+ $data = stream_get_contents($f);
+ if (!empty($data)) {
+ list($storedId, $realId, $server, $version, $expires) = unserialize($data);
+ if ($id === $storedId && $expires > time()) {
+ $ret = true;
+ } else {
+ fclose($f);
+ @unlink($name);
+ fclose($lock);
+ return false;
+ }
+ }
+ fclose($f);
+ fclose($lock);
+ return $ret;
+ }
+
+ /**
+ * Removes cached information discovered from identity $id
+ *
+ * @param string $id identity
+ * @return bool
+ */
+ public function delDiscoveryInfo($id)
+ {
+ $name = $this->_dir . '/discovery_' . md5($id);
+ $lock = @fopen($this->_dir . '/discovery.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ @unlink($name);
+ fclose($lock);
+ return true;
+ }
+
+ /**
+ * The function checks the uniqueness of openid.response_nonce
+ *
+ * @param string $provider openid.openid_op_endpoint field from authentication response
+ * @param string $nonce openid.response_nonce field from authentication response
+ * @return bool
+ */
+ public function isUniqueNonce($provider, $nonce)
+ {
+ $name = $this->_dir . '/nonce_' . md5($provider.';'.$nonce);
+ $lock = @fopen($this->_dir . '/nonce.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name, 'x');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ fwrite($f, $provider.';'.$nonce);
+ fclose($f);
+ fclose($lock);
+ return true;
+ }
+
+ /**
+ * Removes data from the uniqueness database that is older then given date
+ *
+ * @param mixed $date date of expired data
+ */
+ public function purgeNonces($date=null)
+ {
+ $lock = @fopen($this->_dir . '/nonce.lock', 'w+');
+ if ($lock !== false) {
+ flock($lock, LOCK_EX);
+ }
+ if (!is_int($date) && !is_string($date)) {
+ foreach (glob($this->_dir . '/nonce_*') as $name) {
+ @unlink($name);
+ }
+ } else {
+ if (is_string($date)) {
+ $time = time($date);
+ } else {
+ $time = $date;
+ }
+ foreach (glob($this->_dir . '/nonce_*') as $name) {
+ if (filemtime($name) < $time) {
+ @unlink($name);
+ }
+ }
+ }
+ if ($lock !== false) {
+ fclose($lock);
+ }
+ }
+}
diff --git a/applications/core/lib/Zend/OpenId/Exception.php b/applications/core/lib/Zend/OpenId/Exception.php
new file mode 100644
index 0000000..42d21ae
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Exception.php
@@ -0,0 +1,58 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+/**
+ * @see Zend_Exception
+ */
+require_once "Zend/Exception.php";
+
+/**
+ * Exception class for Zend_OpenId
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_OpenId_Exception extends Zend_Exception
+{
+
+ /**
+ * The specified digest algotithm is not supported by this PHP installation
+ */
+ const UNSUPPORTED_DIGEST = 1;
+
+ /**
+ * The long math arithmetick is not supported by this PHP installation
+ */
+ const UNSUPPORTED_LONG_MATH = 2;
+
+ /**
+ * Internal long math arithmetic error
+ */
+ const ERROR_LONG_MATH = 3;
+
+ /**
+ * Iternal storage error
+ */
+ const ERROR_STORAGE = 4;
+}
diff --git a/applications/core/lib/Zend/OpenId/Extension.php b/applications/core/lib/Zend/OpenId/Extension.php
new file mode 100644
index 0000000..9924be0
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Extension.php
@@ -0,0 +1,137 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Extension.php 13522 2009-01-06 16:35:55Z thomas $
+ */
+
+/**
+ * Abstract extension class for Zend_OpenId
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_OpenId_Extension
+{
+
+ /**
+ * Calls given function with given argument for all extensions
+ *
+ * @param mixed $extensions list of extensions or one extension
+ * @param string $func function to be called
+ * @param mixed &$params argument to pass to given funcion
+ * @return bool
+ */
+ static public function forAll($extensions, $func, &$params)
+ {
+ if ($extensions !== null) {
+ if (is_array($extensions)) {
+ foreach ($extensions as $ext) {
+ if ($ext instanceof Zend_OpenId_Extension) {
+ if (!$ext->$func($params)) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ } else if (!is_object($extensions) ||
+ !($extensions instanceof Zend_OpenId_Extension) ||
+ !$extensions->$func($params)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Method to add additional data to OpenId 'checkid_immediate' or
+ * 'checkid_setup' request. This method addes nothing but inherited class
+ * may add additional data into request.
+ *
+ * @param array &$params request's var/val pairs
+ * @return bool
+ */
+ public function prepareRequest(&$params)
+ {
+ return true;
+ }
+
+ /**
+ * Method to parse OpenId 'checkid_immediate' or 'checkid_setup' request
+ * and initialize object with passed data. This method parses nothing but
+ * inherited class may override this method to do somthing.
+ *
+ * @param array $params request's var/val pairs
+ * @return bool
+ */
+ public function parseRequest($params)
+ {
+ return true;
+ }
+
+ /**
+ * Method to add additional data to OpenId 'id_res' response. This method
+ * addes nothing but inherited class may add additional data into response.
+ *
+ * @param array &$params response's var/val pairs
+ * @return bool
+ */
+ public function prepareResponse(&$params)
+ {
+ return true;
+ }
+
+ /**
+ * Method to parse OpenId 'id_res' response and initialize object with
+ * passed data. This method parses nothing but inherited class may override
+ * this method to do somthing.
+ *
+ * @param array $params response's var/val pairs
+ * @return bool
+ */
+ public function parseResponse($params)
+ {
+ return true;
+ }
+
+ /**
+ * Method to prepare data to store it in trusted servers database.
+ *
+ * @param array &$data data to be stored in tusted servers database
+ * @return bool
+ */
+ public function getTrustData(&$data)
+ {
+ return true;
+ }
+
+ /**
+ * Method to check if data from trusted servers database is enough to
+ * sutisfy request.
+ *
+ * @param array $data data from tusted servers database
+ * @return bool
+ */
+ public function checkTrustData($data)
+ {
+ return true;
+ }
+}
diff --git a/applications/core/lib/Zend/OpenId/Extension/Sreg.php b/applications/core/lib/Zend/OpenId/Extension/Sreg.php
new file mode 100644
index 0000000..0ee3e86
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Extension/Sreg.php
@@ -0,0 +1,300 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Sreg.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+/**
+ * @see Zend_OpenId_Extension
+ */
+require_once "Zend/OpenId/Extension.php";
+
+/**
+ * 'Simple Refistration Extension' for Zend_OpenId
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_OpenId_Extension_Sreg extends Zend_OpenId_Extension
+{
+ /**
+ * SREG 1.1 namespace. All OpenID SREG 1.1 messages MUST contain variable
+ * openid.ns.sreg with its value.
+ */
+ const NAMESPACE_1_1 = "http://openid.net/extensions/sreg/1.1";
+
+ private $_props;
+ private $_policy_url;
+ private $_version;
+
+ /**
+ * Creates SREG extension object
+ *
+ * @param array $props associative array of SREG variables
+ * @param string $policy_url SREG policy URL
+ * @param float $version SREG version
+ * @return array
+ */
+ public function __construct(array $props=null, $policy_url=null, $version=1.0)
+ {
+ $this->_props = $props;
+ $this->_policy_url = $policy_url;
+ $this->_version = $version;
+ }
+
+ /**
+ * Returns associative array of SREG variables
+ *
+ * @return array
+ */
+ public function getProperties() {
+ if (is_array($this->_props)) {
+ return $this->_props;
+ } else {
+ return array();
+ }
+ }
+
+ /**
+ * Returns SREG policy URL
+ *
+ * @return string
+ */
+ public function getPolicyUrl() {
+ return $this->_policy_url;
+ }
+
+ /**
+ * Returns SREG protocol version
+ *
+ * @return float
+ */
+ public function getVersion() {
+ return $this->_version;
+ }
+
+ /**
+ * Returns array of allowed SREG variable names.
+ *
+ * @return array
+ */
+ public static function getSregProperties()
+ {
+ return array(
+ "nickname",
+ "email",
+ "fullname",
+ "dob",
+ "gender",
+ "postcode",
+ "country",
+ "language",
+ "timezone"
+ );
+ }
+
+ /**
+ * Adds additional SREG data to OpenId 'checkid_immediate' or
+ * 'checkid_setup' request.
+ *
+ * @param array &$params request's var/val pairs
+ * @return bool
+ */
+ public function prepareRequest(&$params)
+ {
+ if (is_array($this->_props) && count($this->_props) > 0) {
+ foreach ($this->_props as $prop => $req) {
+ if ($req) {
+ if (isset($required)) {
+ $required .= ','.$prop;
+ } else {
+ $required = $prop;
+ }
+ } else {
+ if (isset($optional)) {
+ $optional .= ','.$prop;
+ } else {
+ $optional = $prop;
+ }
+ }
+ }
+ if ($this->_version >= 1.1) {
+ $params['openid.ns.sreg'] = Zend_OpenId_Extension_Sreg::NAMESPACE_1_1;
+ }
+ if (!empty($required)) {
+ $params['openid.sreg.required'] = $required;
+ }
+ if (!empty($optional)) {
+ $params['openid.sreg.optional'] = $optional;
+ }
+ if (!empty($this->_policy_url)) {
+ $params['openid.sreg.policy_url'] = $this->_policy_url;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Parses OpenId 'checkid_immediate' or 'checkid_setup' request,
+ * extracts SREG variables and sets ovject properties to corresponding
+ * values.
+ *
+ * @param array $params request's var/val pairs
+ * @return bool
+ */
+ public function parseRequest($params)
+ {
+ if (isset($params['openid_ns_sreg']) &&
+ $params['openid_ns_sreg'] === Zend_OpenId_Extension_Sreg::NAMESPACE_1_1) {
+ $this->_version= 1.1;
+ } else {
+ $this->_version= 1.0;
+ }
+ if (!empty($params['openid_sreg_policy_url'])) {
+ $this->_policy_url = $params['openid_sreg_policy_url'];
+ } else {
+ $this->_policy_url = null;
+ }
+ $props = array();
+ if (!empty($params['openid_sreg_optional'])) {
+ foreach (explode(',', $params['openid_sreg_optional']) as $prop) {
+ $prop = trim($prop);
+ $props[$prop] = false;
+ }
+ }
+ if (!empty($params['openid_sreg_required'])) {
+ foreach (explode(',', $params['openid_sreg_required']) as $prop) {
+ $prop = trim($prop);
+ $props[$prop] = true;
+ }
+ }
+ $props2 = array();
+ foreach (self::getSregProperties() as $prop) {
+ if (isset($props[$prop])) {
+ $props2[$prop] = $props[$prop];
+ }
+ }
+
+ $this->_props = (count($props2) > 0) ? $props2 : null;
+ return true;
+ }
+
+ /**
+ * Adds additional SREG data to OpenId 'id_res' response.
+ *
+ * @param array &$params response's var/val pairs
+ * @return bool
+ */
+ public function prepareResponse(&$params)
+ {
+ if (is_array($this->_props) && count($this->_props) > 0) {
+ if ($this->_version >= 1.1) {
+ $params['openid.ns.sreg'] = Zend_OpenId_Extension_Sreg::NAMESPACE_1_1;
+ }
+ foreach (self::getSregProperties() as $prop) {
+ if (!empty($this->_props[$prop])) {
+ $params['openid.sreg.' . $prop] = $this->_props[$prop];
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Parses OpenId 'id_res' response and sets object's properties according
+ * to 'openid.sreg.*' variables in response
+ *
+ * @param array $params response's var/val pairs
+ * @return bool
+ */
+ public function parseResponse($params)
+ {
+ if (isset($params['openid_ns_sreg']) &&
+ $params['openid_ns_sreg'] === Zend_OpenId_Extension_Sreg::NAMESPACE_1_1) {
+ $this->_version= 1.1;
+ } else {
+ $this->_version= 1.0;
+ }
+ $props = array();
+ foreach (self::getSregProperties() as $prop) {
+ if (!empty($params['openid_sreg_' . $prop])) {
+ $props[$prop] = $params['openid_sreg_' . $prop];
+ }
+ }
+ if (isset($this->_props) && is_array($this->_props)) {
+ foreach (self::getSregProperties() as $prop) {
+ if (isset($this->_props[$prop]) &&
+ $this->_props[$prop] &&
+ !isset($props[$prop])) {
+ return false;
+ }
+ }
+ }
+ $this->_props = (count($props) > 0) ? $props : null;
+ return true;
+ }
+
+ /**
+ * Addes SREG properties that are allowed to be send to consumer to
+ * the given $data argument.
+ *
+ * @param array &$data data to be stored in tusted servers database
+ * @return bool
+ */
+ public function getTrustData(&$data)
+ {
+ $data[get_class()] = $this->getProperties();
+ return true;
+ }
+
+ /**
+ * Check if given $data contains necessury SREG properties to sutisfy
+ * OpenId request. On success sets SREG response properties from given
+ * $data and returns true, on failure returns false.
+ *
+ * @param array $data data from tusted servers database
+ * @return bool
+ */
+ public function checkTrustData($data)
+ {
+ if (is_array($this->_props) && count($this->_props) > 0) {
+ $props = array();
+ $name = get_class();
+ if (isset($data[$name])) {
+ $props = $data[$name];
+ } else {
+ $props = array();
+ }
+ $props2 = array();
+ foreach ($this->_props as $prop => $req) {
+ if (empty($props[$prop])) {
+ if ($req) {
+ return false;
+ }
+ } else {
+ $props2[$prop] = $props[$prop];
+ }
+ }
+ $this->_props = (count($props2) > 0) ? $props2 : null;
+ }
+ return true;
+ }
+}
diff --git a/applications/core/lib/Zend/OpenId/Provider.php b/applications/core/lib/Zend/OpenId/Provider.php
new file mode 100644
index 0000000..c1a10ef
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Provider.php
@@ -0,0 +1,781 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Provider
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Provider.php 13522 2009-01-06 16:35:55Z thomas $
+ */
+
+/**
+ * @see Zend_OpenId
+ */
+require_once "Zend/OpenId.php";
+
+/**
+ * @see Zend_OpenId_Extension
+ */
+require_once "Zend/OpenId/Extension.php";
+
+/**
+ * OpenID provider (server) implementation
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Provider
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_OpenId_Provider
+{
+
+ /**
+ * Reference to an implementation of storage object
+ *
+ * @var Zend_OpenId_Provider_Storage $_storage
+ */
+ private $_storage;
+
+ /**
+ * Reference to an implementation of user object
+ *
+ * @var Zend_OpenId_Provider_User $_user
+ */
+ private $_user;
+
+ /**
+ * Time to live of association session in secconds
+ *
+ * @var integer $_sessionTtl
+ */
+ private $_sessionTtl;
+
+ /**
+ * URL to peform interactive user login
+ *
+ * @var string $_loginUrl
+ */
+ private $_loginUrl;
+
+ /**
+ * URL to peform interactive validation of consumer by user
+ *
+ * @var string $_trustUrl
+ */
+ private $_trustUrl;
+
+ /**
+ * The OP Endpoint URL
+ *
+ * @var string $_opEndpoint
+ */
+ private $_opEndpoint;
+
+ /**
+ * Constructs a Zend_OpenId_Provider object with given parameters.
+ *
+ * @param string $loginUrl is an URL that provides login screen for
+ * end-user (by default it is the same URL with additional GET variable
+ * openid.action=login)
+ * @param string $trustUrl is an URL that shows a question if end-user
+ * trust to given consumer (by default it is the same URL with additional
+ * GET variable openid.action=trust)
+ * @param Zend_OpenId_Provider_User $user is an object for communication
+ * with User-Agent and store information about logged-in user (it is a
+ * Zend_OpenId_Provider_User_Session object by default)
+ * @param Zend_OpenId_Provider_Storage $storage is an object for keeping
+ * persistent database (it is a Zend_OpenId_Provider_Storage_File object
+ * by default)
+ * @param integer $sessionTtl is a default time to live for association
+ * session in seconds (1 hour by default). Consumer must reestablish
+ * association after that time.
+ */
+ public function __construct($loginUrl = null,
+ $trustUrl = null,
+ Zend_OpenId_Provider_User $user = null,
+ Zend_OpenId_Provider_Storage $storage = null,
+ $sessionTtl = 3600)
+ {
+ if ($loginUrl === null) {
+ $loginUrl = Zend_OpenId::selfUrl() . '?openid.action=login';
+ } else {
+ $loginUrl = Zend_OpenId::absoluteUrl($loginUrl);
+ }
+ $this->_loginUrl = $loginUrl;
+ if ($trustUrl === null) {
+ $trustUrl = Zend_OpenId::selfUrl() . '?openid.action=trust';
+ } else {
+ $trustUrl = Zend_OpenId::absoluteUrl($trustUrl);
+ }
+ $this->_trustUrl = $trustUrl;
+ if ($user === null) {
+ require_once "Zend/OpenId/Provider/User/Session.php";
+ $this->_user = new Zend_OpenId_Provider_User_Session();
+ } else {
+ $this->_user = $user;
+ }
+ if ($storage === null) {
+ require_once "Zend/OpenId/Provider/Storage/File.php";
+ $this->_storage = new Zend_OpenId_Provider_Storage_File();
+ } else {
+ $this->_storage = $storage;
+ }
+ $this->_sessionTtl = $sessionTtl;
+ }
+
+ /**
+ * Sets the OP Endpoint URL
+ *
+ * @param string $url the OP Endpoint URL
+ * @return null
+ */
+ public function setOpEndpoint($url)
+ {
+ $this->_opEndpoint = $url;
+ }
+
+ /**
+ * Registers a new user with given $id and $password
+ * Returns true in case of success and false if user with given $id already
+ * exists
+ *
+ * @param string $id user identity URL
+ * @param string $password encoded user password
+ * @return bool
+ */
+ public function register($id, $password)
+ {
+ if (!Zend_OpenId::normalize($id) || empty($id)) {
+ return false;
+ }
+ return $this->_storage->addUser($id, md5($id.$password));
+ }
+
+ /**
+ * Returns true if user with given $id exists and false otherwise
+ *
+ * @param string $id user identity URL
+ * @return bool
+ */
+ public function hasUser($id) {
+ if (!Zend_OpenId::normalize($id)) {
+ return false;
+ }
+ return $this->_storage->hasUser($id);
+ }
+
+ /**
+ * Performs login of user with given $id and $password
+ * Returns true in case of success and false otherwise
+ *
+ * @param string $id user identity URL
+ * @param string $password user password
+ * @return bool
+ */
+ public function login($id, $password)
+ {
+ if (!Zend_OpenId::normalize($id)) {
+ return false;
+ }
+ if (!$this->_storage->checkUser($id, md5($id.$password))) {
+ return false;
+ }
+ $this->_user->setLoggedInUser($id);
+ return true;
+ }
+
+ /**
+ * Performs logout. Clears information about logged in user.
+ *
+ * @return void
+ */
+ public function logout()
+ {
+ $this->_user->delLoggedInUser();
+ return true;
+ }
+
+ /**
+ * Returns identity URL of current logged in user or false
+ *
+ * @return mixed
+ */
+ public function getLoggedInUser() {
+ return $this->_user->getLoggedInUser();
+ }
+
+ /**
+ * Retrieve consumer's root URL from request query.
+ * Returns URL or false in case of failure
+ *
+ * @param array $params query arguments
+ * @return mixed
+ */
+ public function getSiteRoot($params)
+ {
+ $version = 1.1;
+ if (isset($params['openid_ns']) &&
+ $params['openid_ns'] == Zend_OpenId::NS_2_0) {
+ $version = 2.0;
+ }
+ if ($version >= 2.0 && isset($params['openid_realm'])) {
+ $root = $params['openid_realm'];
+ } else if ($version < 2.0 && isset($params['openid_trust_root'])) {
+ $root = $params['openid_trust_root'];
+ } else if (isset($params['openid_return_to'])) {
+ $root = $params['openid_return_to'];
+ } else {
+ return false;
+ }
+ if (Zend_OpenId::normalizeUrl($root) && !empty($root)) {
+ return $root;
+ }
+ return false;
+ }
+
+ /**
+ * Allows consumer with given root URL to authenticate current logged
+ * in user. Returns true on success and false on error.
+ *
+ * @param string $root root URL
+ * @param mixed $extensions extension object or array of extensions objects
+ * @return bool
+ */
+ public function allowSite($root, $extensions=null)
+ {
+ $id = $this->getLoggedInUser();
+ if ($id === false) {
+ return false;
+ }
+ if ($extensions !== null) {
+ $data = array();
+ Zend_OpenId_Extension::forAll($extensions, 'getTrustData', $data);
+ } else {
+ $data = true;
+ }
+ $this->_storage->addSite($id, $root, $data);
+ return true;
+ }
+
+ /**
+ * Prohibit consumer with given root URL to authenticate current logged
+ * in user. Returns true on success and false on error.
+ *
+ * @param string $root root URL
+ * @return bool
+ */
+ public function denySite($root)
+ {
+ $id = $this->getLoggedInUser();
+ if ($id === false) {
+ return false;
+ }
+ $this->_storage->addSite($id, $root, false);
+ return true;
+ }
+
+ /**
+ * Delete consumer with given root URL from known sites of current logged
+ * in user. Next time this consumer will try to authenticate the user,
+ * Provider will ask user's confirmation.
+ * Returns true on success and false on error.
+ *
+ * @param string $root root URL
+ * @return bool
+ */
+ public function delSite($root)
+ {
+ $id = $this->getLoggedInUser();
+ if ($id === false) {
+ return false;
+ }
+ $this->_storage->addSite($id, $root, null);
+ return true;
+ }
+
+ /**
+ * Returns list of known consumers for current logged in user or false
+ * if he is not logged in.
+ *
+ * @return mixed
+ */
+ public function getTrustedSites()
+ {
+ $id = $this->getLoggedInUser();
+ if ($id === false) {
+ return false;
+ }
+ return $this->_storage->getTrustedSites($id);
+ }
+
+ /**
+ * Handles HTTP request from consumer
+ *
+ * @param array $params GET or POST variables. If this parameter is omited
+ * or set to null, then $_GET or $_POST superglobal variable is used
+ * according to REQUEST_METHOD.
+ * @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 mixed
+ */
+ public function handle($params=null, $extensions=null,
+ Zend_Controller_Response_Abstract $response = null)
+ {
+ if ($params === null) {
+ if ($_SERVER["REQUEST_METHOD"] == "GET") {
+ $params = $_GET;
+ } else if ($_SERVER["REQUEST_METHOD"] == "POST") {
+ $params = $_POST;
+ } else {
+ return false;
+ }
+ }
+ $version = 1.1;
+ if (isset($params['openid_ns']) &&
+ $params['openid_ns'] == Zend_OpenId::NS_2_0) {
+ $version = 2.0;
+ }
+ if (isset($params['openid_mode'])) {
+ if ($params['openid_mode'] == 'associate') {
+ $response = $this->_associate($version, $params);
+ $ret = '';
+ foreach ($response as $key => $val) {
+ $ret .= $key . ':' . $val . "\n";
+ }
+ return $ret;
+ } else if ($params['openid_mode'] == 'checkid_immediate') {
+ $ret = $this->_checkId($version, $params, 1, $extensions, $response);
+ if (is_bool($ret)) return $ret;
+ if (!empty($params['openid_return_to'])) {
+ Zend_OpenId::redirect($params['openid_return_to'], $ret, $response);
+ }
+ return true;
+ } else if ($params['openid_mode'] == 'checkid_setup') {
+ $ret = $this->_checkId($version, $params, 0, $extensions, $response);
+ if (is_bool($ret)) return $ret;
+ if (!empty($params['openid_return_to'])) {
+ Zend_OpenId::redirect($params['openid_return_to'], $ret, $response);
+ }
+ return true;
+ } else if ($params['openid_mode'] == 'check_authentication') {
+ $response = $this->_checkAuthentication($version, $params);
+ $ret = '';
+ foreach ($response as $key => $val) {
+ $ret .= $key . ':' . $val . "\n";
+ }
+ return $ret;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Generates a secret key for given hash function, returns RAW key or false
+ * if function is not supported
+ *
+ * @param string $func hash function (sha1 or sha256)
+ * @return mixed
+ */
+ protected function _genSecret($func)
+ {
+ if ($func == 'sha1') {
+ $macLen = 20; /* 160 bit */
+ } else if ($func == 'sha256') {
+ $macLen = 32; /* 256 bit */
+ } else {
+ return false;
+ }
+ return Zend_OpenId::randomBytes($macLen);
+ }
+
+ /**
+ * Processes association request from OpenID consumerm generates secret
+ * shared key and send it back using Diffie-Hellman encruption.
+ * Returns array of variables to push back to consumer.
+ *
+ * @param float $version OpenID version
+ * @param array $params GET or POST request variables
+ * @return array
+ */
+ protected function _associate($version, $params)
+ {
+ $ret = array();
+
+ if ($version >= 2.0) {
+ $ret['ns'] = Zend_OpenId::NS_2_0;
+ }
+
+ if (isset($params['openid_assoc_type']) &&
+ $params['openid_assoc_type'] == 'HMAC-SHA1') {
+ $macFunc = 'sha1';
+ } else if (isset($params['openid_assoc_type']) &&
+ $params['openid_assoc_type'] == 'HMAC-SHA256' &&
+ $version >= 2.0) {
+ $macFunc = 'sha256';
+ } else {
+ $ret['error'] = 'Wrong "openid.assoc_type"';
+ $ret['error-code'] = 'unsupported-type';
+ return $ret;
+ }
+
+ $ret['assoc_type'] = $params['openid_assoc_type'];
+
+ $secret = $this->_genSecret($macFunc);
+
+ if (empty($params['openid_session_type']) ||
+ $params['openid_session_type'] == 'no-encryption') {
+ $ret['mac_key'] = base64_encode($secret);
+ } else if (isset($params['openid_session_type']) &&
+ $params['openid_session_type'] == 'DH-SHA1') {
+ $dhFunc = 'sha1';
+ } else if (isset($params['openid_session_type']) &&
+ $params['openid_session_type'] == 'DH-SHA256' &&
+ $version >= 2.0) {
+ $dhFunc = 'sha256';
+ } else {
+ $ret['error'] = 'Wrong "openid.session_type"';
+ $ret['error-code'] = 'unsupported-type';
+ return $ret;
+ }
+
+ if (isset($params['openid_session_type'])) {
+ $ret['session_type'] = $params['openid_session_type'];
+ }
+
+ if (isset($dhFunc)) {
+ if (empty($params['openid_dh_consumer_public'])) {
+ $ret['error'] = 'Wrong "openid.dh_consumer_public"';
+ return $ret;
+ }
+ if (empty($params['openid_dh_gen'])) {
+ $g = pack('H*', Zend_OpenId::DH_G);
+ } else {
+ $g = base64_decode($params['openid_dh_gen']);
+ }
+ if (empty($params['openid_dh_modulus'])) {
+ $p = pack('H*', Zend_OpenId::DH_P);
+ } else {
+ $p = base64_decode($params['openid_dh_modulus']);
+ }
+
+ $dh = Zend_OpenId::createDhKey($p, $g);
+ $dh_details = Zend_OpenId::getDhKeyDetails($dh);
+
+ $sec = Zend_OpenId::computeDhSecret(
+ base64_decode($params['openid_dh_consumer_public']), $dh);
+ if ($sec === false) {
+ $ret['error'] = 'Wrong "openid.session_type"';
+ $ret['error-code'] = 'unsupported-type';
+ return $ret;
+ }
+ $sec = Zend_OpenId::digest($dhFunc, $sec);
+ $ret['dh_server_public'] = base64_encode(
+ Zend_OpenId::btwoc($dh_details['pub_key']));
+ $ret['enc_mac_key'] = base64_encode($secret ^ $sec);
+ }
+
+ $handle = uniqid();
+ $expiresIn = $this->_sessionTtl;
+
+ $ret['assoc_handle'] = $handle;
+ $ret['expires_in'] = $expiresIn;
+
+ $this->_storage->addAssociation($handle,
+ $macFunc, $secret, time() + $expiresIn);
+
+ return $ret;
+ }
+
+ /**
+ * Performs authentication (or authentication check).
+ *
+ * @param float $version OpenID version
+ * @param array $params GET or POST request variables
+ * @param bool $immediate enables or disables interaction with user
+ * @param mixed $extensions extension object or array of extensions objects
+ * @param Zend_Controller_Response_Abstract $response
+ * @return array
+ */
+ protected function _checkId($version, $params, $immediate, $extensions=null,
+ Zend_Controller_Response_Abstract $response = null)
+ {
+ $ret = array();
+
+ if ($version >= 2.0) {
+ $ret['openid.ns'] = Zend_OpenId::NS_2_0;
+ }
+ $root = $this->getSiteRoot($params);
+ if ($root === false) {
+ return false;
+ }
+
+ if (isset($params['openid_identity']) &&
+ !$this->_storage->hasUser($params['openid_identity'])) {
+ $ret['openid.mode'] = ($immediate && $version >= 2.0) ? 'setup_needed': 'cancel';
+ return $ret;
+ }
+
+ /* Check if user already logged in into the server */
+ if (!isset($params['openid_identity']) ||
+ $this->_user->getLoggedInUser() !== $params['openid_identity']) {
+ $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;
+ }
+ if ($immediate) {
+ $params2['openid.mode'] = 'checkid_setup';
+ $ret['openid.mode'] = ($version >= 2.0) ? 'setup_needed': 'id_res';
+ $ret['openid.user_setup_url'] = $this->_loginUrl
+ . (strpos($this->_loginUrl, '?') === false ? '?' : '&')
+ . Zend_OpenId::paramsToQuery($params2);
+ return $ret;
+ } else {
+ /* Redirect to Server Login Screen */
+ Zend_OpenId::redirect($this->_loginUrl, $params2, $response);
+ return true;
+ }
+ }
+
+ if (!Zend_OpenId_Extension::forAll($extensions, 'parseRequest', $params)) {
+ $ret['openid.mode'] = ($immediate && $version >= 2.0) ? 'setup_needed': 'cancel';
+ return $ret;
+ }
+
+ /* Check if user trusts to the consumer */
+ $trusted = null;
+ $sites = $this->_storage->getTrustedSites($params['openid_identity']);
+ if (isset($params['openid_return_to'])) {
+ $root = $params['openid_return_to'];
+ }
+ if (isset($sites[$root])) {
+ $trusted = $sites[$root];
+ } else {
+ foreach ($sites as $site => $t) {
+ if (strpos($root, $site) === 0) {
+ $trusted = $t;
+ break;
+ } else {
+ /* OpenID 2.0 (9.2) check for realm wild-card matching */
+ $n = strpos($site, '://*.');
+ if ($n != false) {
+ $regex = '/^'
+ . preg_quote(substr($site, 0, $n+3), '/')
+ . '[A-Za-z1-9_\.]+?'
+ . preg_quote(substr($site, $n+4), '/')
+ . '/';
+ if (preg_match($regex, $root)) {
+ $trusted = $t;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (is_array($trusted)) {
+ if (!Zend_OpenId_Extension::forAll($extensions, 'checkTrustData', $trusted)) {
+ $trusted = null;
+ }
+ }
+
+ if ($trusted === false) {
+ $ret['openid.mode'] = 'cancel';
+ return $ret;
+ } else if ($trusted === null) {
+ /* Redirect to Server Trust Screen */
+ $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;
+ }
+ if ($immediate) {
+ $params2['openid.mode'] = 'checkid_setup';
+ $ret['openid.mode'] = ($version >= 2.0) ? 'setup_needed': 'id_res';
+ $ret['openid.user_setup_url'] = $this->_trustUrl
+ . (strpos($this->_trustUrl, '?') === false ? '?' : '&')
+ . Zend_OpenId::paramsToQuery($params2);
+ return $ret;
+ } else {
+ Zend_OpenId::redirect($this->_trustUrl, $params2, $response);
+ return true;
+ }
+ }
+
+ return $this->_respond($version, $ret, $params, $extensions);
+ }
+
+ /**
+ * Perepares information to send back to consumer's authentication request,
+ * signs it using shared secret and send back through HTTP redirection
+ *
+ * @param array $params GET or POST request variables
+ * @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 respondToConsumer($params, $extensions=null,
+ Zend_Controller_Response_Abstract $response = null)
+ {
+ $version = 1.1;
+ if (isset($params['openid_ns']) &&
+ $params['openid_ns'] == Zend_OpenId::NS_2_0) {
+ $version = 2.0;
+ }
+ $ret = array();
+ if ($version >= 2.0) {
+ $ret['openid.ns'] = Zend_OpenId::NS_2_0;
+ }
+ $ret = $this->_respond($version, $ret, $params, $extensions);
+ if (!empty($params['openid_return_to'])) {
+ Zend_OpenId::redirect($params['openid_return_to'], $ret, $response);
+ }
+ return true;
+ }
+
+ /**
+ * Perepares information to send back to consumer's authentication request
+ * and signs it using shared secret.
+ *
+ * @param float $version OpenID protcol version
+ * @param array $ret arguments to be send back to consumer
+ * @param array $params GET or POST request variables
+ * @param mixed $extensions extension object or array of extensions objects
+ * @return array
+ */
+ protected function _respond($version, $ret, $params, $extensions=null)
+ {
+ if (empty($params['openid_assoc_handle']) ||
+ !$this->_storage->getAssociation($params['openid_assoc_handle'],
+ $macFunc, $secret, $expires)) {
+ /* Use dumb mode */
+ if (!empty($params['openid_assoc_handle'])) {
+ $ret['openid.invalidate_handle'] = $params['openid_assoc_handle'];
+ }
+ $macFunc = $version >= 2.0 ? 'sha256' : 'sha1';
+ $secret = $this->_genSecret($macFunc);
+ $handle = uniqid();
+ $expiresIn = $this->_sessionTtl;
+ $this->_storage->addAssociation($handle,
+ $macFunc, $secret, time() + $expiresIn);
+ $ret['openid.assoc_handle'] = $handle;
+ } else {
+ $ret['openid.assoc_handle'] = $params['openid_assoc_handle'];
+ }
+ if (isset($params['openid_return_to'])) {
+ $ret['openid.return_to'] = $params['openid_return_to'];
+ }
+ if (isset($params['openid_claimed_id'])) {
+ $ret['openid.claimed_id'] = $params['openid_claimed_id'];
+ }
+ if (isset($params['openid_identity'])) {
+ $ret['openid.identity'] = $params['openid_identity'];
+ }
+
+ if ($version >= 2.0) {
+ if (!empty($this->_opEndpoint)) {
+ $ret['openid.op_endpoint'] = $this->_opEndpoint;
+ } else {
+ $ret['openid.op_endpoint'] = Zend_OpenId::selfUrl();
+ }
+ }
+ $ret['openid.response_nonce'] = gmdate('Y-m-d\TH:i:s\Z') . uniqid();
+ $ret['openid.mode'] = 'id_res';
+
+ Zend_OpenId_Extension::forAll($extensions, 'prepareResponse', $ret);
+
+ $signed = '';
+ $data = '';
+ foreach ($ret as $key => $val) {
+ if (strpos($key, 'openid.') === 0) {
+ $key = substr($key, strlen('openid.'));
+ if (!empty($signed)) {
+ $signed .= ',';
+ }
+ $signed .= $key;
+ $data .= $key . ':' . $val . "\n";
+ }
+ }
+ $signed .= ',signed';
+ $data .= 'signed:' . $signed . "\n";
+ $ret['openid.signed'] = $signed;
+
+ $ret['openid.sig'] = base64_encode(
+ Zend_OpenId::hashHmac($macFunc, $data, $secret));
+
+ return $ret;
+ }
+
+ /**
+ * Performs authentication validation for dumb consumers
+ * Returns array of variables to push back to consumer.
+ * It MUST contain 'is_valid' variable with value 'true' or 'false'.
+ *
+ * @param float $version OpenID version
+ * @param array $params GET or POST request variables
+ * @return array
+ */
+ protected function _checkAuthentication($version, $params)
+ {
+ $ret = array();
+ if ($version >= 2.0) {
+ $ret['ns'] = Zend_OpenId::NS_2_0;
+ }
+ $ret['openid.mode'] = 'id_res';
+
+ if (empty($params['openid_assoc_handle']) ||
+ empty($params['openid_signed']) ||
+ empty($params['openid_sig']) ||
+ !$this->_storage->getAssociation($params['openid_assoc_handle'],
+ $macFunc, $secret, $expires)) {
+ $ret['is_valid'] = 'false';
+ return $ret;
+ }
+
+ $signed = explode(',', $params['openid_signed']);
+ $data = '';
+ foreach ($signed as $key) {
+ $data .= $key . ':';
+ if ($key == 'mode') {
+ $data .= "id_res\n";
+ } else {
+ $data .= $params['openid_' . strtr($key,'.','_')]."\n";
+ }
+ }
+ if (base64_decode($params['openid_sig']) ===
+ Zend_OpenId::hashHmac($macFunc, $data, $secret)) {
+ $ret['is_valid'] = 'true';
+ } else {
+ $ret['is_valid'] = 'false';
+ }
+ return $ret;
+ }
+}
diff --git a/applications/core/lib/Zend/OpenId/Provider/Storage.php b/applications/core/lib/Zend/OpenId/Provider/Storage.php
new file mode 100644
index 0000000..53aa7cd
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Provider/Storage.php
@@ -0,0 +1,106 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Provider
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Storage.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+/**
+ * Abstract class to implement external storage for OpenID consumer
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Provider
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_OpenId_Provider_Storage
+{
+
+ /**
+ * Stores information about session identified by $handle
+ *
+ * @param string $handle assiciation handle
+ * @param string $macFunc HMAC function (sha1 or sha256)
+ * @param string $secret shared secret
+ * @param string $expires expiration UNIX time
+ * @return void
+ */
+ abstract public function addAssociation($handle, $macFunc, $secret, $expires);
+
+ /**
+ * Gets information about association identified by $handle
+ * Returns true if given association found and not expired and false
+ * otherwise
+ *
+ * @param string $handle assiciation handle
+ * @param string &$macFunc HMAC function (sha1 or sha256)
+ * @param string &$secret shared secret
+ * @param string &$expires expiration UNIX time
+ * @return bool
+ */
+ abstract public function getAssociation($handle, &$macFunc, &$secret, &$expires);
+
+ /**
+ * Register new user with given $id and $password
+ * Returns true in case of success and false if user with given $id already
+ * exists
+ *
+ * @param string $id user identity URL
+ * @param string $password encoded user password
+ * @return bool
+ */
+ abstract public function addUser($id, $password);
+
+ /**
+ * Returns true if user with given $id exists and false otherwise
+ *
+ * @param string $id user identity URL
+ * @return bool
+ */
+ abstract public function hasUser($id);
+
+ /**
+ * Verify if user with given $id exists and has specified $password
+ *
+ * @param string $id user identity URL
+ * @param string $password user password
+ * @return bool
+ */
+ abstract public function checkUser($id, $password);
+
+ /**
+ * Returns array of all trusted/untrusted sites for given user identified
+ * by $id
+ *
+ * @param string $id user identity URL
+ * @return array
+ */
+ abstract public function getTrustedSites($id);
+
+ /**
+ * Stores information about trusted/untrusted site for given user
+ *
+ * @param string $id user identity URL
+ * @param string $site site URL
+ * @param mixed $trusted trust data from extensions or just a boolean value
+ * @return bool
+ */
+ abstract public function addSite($id, $site, $trusted);
+}
diff --git a/applications/core/lib/Zend/OpenId/Provider/Storage/File.php b/applications/core/lib/Zend/OpenId/Provider/Storage/File.php
new file mode 100644
index 0000000..6169766
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Provider/Storage/File.php
@@ -0,0 +1,397 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Provider
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: File.php 13522 2009-01-06 16:35:55Z thomas $
+ */
+
+/**
+ * @see Zend_OpenId_Provider_Storage
+ */
+require_once "Zend/OpenId/Provider/Storage.php";
+
+/**
+ * External storage implemmentation using serialized files
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Provider
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_OpenId_Provider_Storage_File extends Zend_OpenId_Provider_Storage
+{
+
+ /**
+ * Directory name to store data files in
+ *
+ * @var string $_dir
+ */
+ private $_dir;
+
+ /**
+ * Constructs storage object and creates storage directory
+ *
+ * @param string $dir directory name to store data files in
+ * @throws Zend_OpenId_Exception
+ */
+ public function __construct($dir = null)
+ {
+ if ($dir === null) {
+ $tmp = getenv('TMP');
+ if (empty($tmp)) {
+ $tmp = getenv('TEMP');
+ if (empty($tmp)) {
+ $tmp = "/tmp";
+ }
+ }
+ $user = get_current_user();
+ if (is_string($user) && !empty($user)) {
+ $tmp .= '/' . $user;
+ }
+ $dir = $tmp . '/openid/provider';
+ }
+ $this->_dir = $dir;
+ if (!is_dir($this->_dir)) {
+ if (!@mkdir($this->_dir, 0700, 1)) {
+ throw new Zend_OpenId_Exception(
+ "Cannot access storage directory $dir",
+ Zend_OpenId_Exception::ERROR_STORAGE);
+ }
+ }
+ if (($f = fopen($this->_dir.'/assoc.lock', 'w+')) === null) {
+ throw new Zend_OpenId_Exception(
+ 'Cannot create a lock file in the directory ' . $dir,
+ Zend_OpenId_Exception::ERROR_STORAGE);
+ }
+ fclose($f);
+ if (($f = fopen($this->_dir.'/user.lock', 'w+')) === null) {
+ throw new Zend_OpenId_Exception(
+ 'Cannot create a lock file in the directory ' . $dir,
+ Zend_OpenId_Exception::ERROR_STORAGE);
+ }
+ fclose($f);
+ }
+
+ /**
+ * Stores information about session identified by $handle
+ *
+ * @param string $handle assiciation handle
+ * @param string $macFunc HMAC function (sha1 or sha256)
+ * @param string $secret shared secret
+ * @param string $expires expiration UNIX time
+ * @return bool
+ */
+ public function addAssociation($handle, $macFunc, $secret, $expires)
+ {
+ $name = $this->_dir . '/assoc_' . md5($handle);
+ $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name, 'w+');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $data = serialize(array($handle, $macFunc, $secret, $expires));
+ fwrite($f, $data);
+ fclose($f);
+ fclose($lock);
+ return true;
+ }
+
+ /**
+ * Gets information about association identified by $handle
+ * Returns true if given association found and not expired and false
+ * otherwise
+ *
+ * @param string $handle assiciation handle
+ * @param string &$macFunc HMAC function (sha1 or sha256)
+ * @param string &$secret shared secret
+ * @param string &$expires expiration UNIX time
+ * @return bool
+ */
+ public function getAssociation($handle, &$macFunc, &$secret, &$expires)
+ {
+ $name = $this->_dir . '/assoc_' . md5($handle);
+ $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name, 'r');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $ret = false;
+ $data = stream_get_contents($f);
+ if (!empty($data)) {
+ list($storedHandle, $macFunc, $secret, $expires) = unserialize($data);
+ if ($handle === $storedHandle && $expires > time()) {
+ $ret = true;
+ } else {
+ fclose($f);
+ @unlink($name);
+ fclose($lock);
+ return false;
+ }
+ }
+ fclose($f);
+ fclose($lock);
+ return $ret;
+ }
+
+ /**
+ * Removes information about association identified by $handle
+ *
+ * @param string $handle assiciation handle
+ * @return bool
+ */
+ public function delAssociation($handle)
+ {
+ $name = $this->_dir . '/assoc_' . md5($handle);
+ $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ @unlink($name);
+ fclose($lock);
+ return true;
+ }
+
+ /**
+ * Register new user with given $id and $password
+ * Returns true in case of success and false if user with given $id already
+ * exists
+ *
+ * @param string $id user identity URL
+ * @param string $password encoded user password
+ * @return bool
+ */
+ public function addUser($id, $password)
+ {
+ $name = $this->_dir . '/user_' . md5($id);
+ $lock = @fopen($this->_dir . '/user.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name, 'x');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $data = serialize(array($id, $password, array()));
+ fwrite($f, $data);
+ fclose($f);
+ fclose($lock);
+ return true;
+ }
+
+ /**
+ * Returns true if user with given $id exists and false otherwise
+ *
+ * @param string $id user identity URL
+ * @return bool
+ */
+ public function hasUser($id)
+ {
+ $name = $this->_dir . '/user_' . md5($id);
+ $lock = @fopen($this->_dir . '/user.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_SH)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name, 'r');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $ret = false;
+ $data = stream_get_contents($f);
+ if (!empty($data)) {
+ list($storedId, $storedPassword, $trusted) = unserialize($data);
+ if ($id === $storedId) {
+ $ret = true;
+ }
+ }
+ fclose($f);
+ fclose($lock);
+ return $ret;
+ }
+
+ /**
+ * Verify if user with given $id exists and has specified $password
+ *
+ * @param string $id user identity URL
+ * @param string $password user password
+ * @return bool
+ */
+ public function checkUser($id, $password)
+ {
+ $name = $this->_dir . '/user_' . md5($id);
+ $lock = @fopen($this->_dir . '/user.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_SH)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name, 'r');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $ret = false;
+ $data = stream_get_contents($f);
+ if (!empty($data)) {
+ list($storedId, $storedPassword, $trusted) = unserialize($data);
+ if ($id === $storedId && $password === $storedPassword) {
+ $ret = true;
+ }
+ }
+ fclose($f);
+ fclose($lock);
+ return $ret;
+ }
+
+ /**
+ * Removes information abou specified user
+ *
+ * @param string $id user identity URL
+ * @return bool
+ */
+ public function delUser($id)
+ {
+ $name = $this->_dir . '/user_' . md5($id);
+ $lock = @fopen($this->_dir . '/user.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ @unlink($name);
+ fclose($lock);
+ return true;
+ }
+
+ /**
+ * Returns array of all trusted/untrusted sites for given user identified
+ * by $id
+ *
+ * @param string $id user identity URL
+ * @return array
+ */
+ public function getTrustedSites($id)
+ {
+ $name = $this->_dir . '/user_' . md5($id);
+ $lock = @fopen($this->_dir . '/user.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_SH)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name, 'r');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $ret = false;
+ $data = stream_get_contents($f);
+ if (!empty($data)) {
+ list($storedId, $storedPassword, $trusted) = unserialize($data);
+ if ($id === $storedId) {
+ $ret = $trusted;
+ }
+ }
+ fclose($f);
+ fclose($lock);
+ return $ret;
+ }
+
+ /**
+ * Stores information about trusted/untrusted site for given user
+ *
+ * @param string $id user identity URL
+ * @param string $site site URL
+ * @param mixed $trusted trust data from extension or just a boolean value
+ * @return bool
+ */
+ public function addSite($id, $site, $trusted)
+ {
+ $name = $this->_dir . '/user_' . md5($id);
+ $lock = @fopen($this->_dir . '/user.lock', 'w+');
+ if ($lock === false) {
+ return false;
+ }
+ if (!flock($lock, LOCK_EX)) {
+ fclose($lock);
+ return false;
+ }
+ $f = @fopen($name, 'r+');
+ if ($f === false) {
+ fclose($lock);
+ return false;
+ }
+ $ret = false;
+ $data = stream_get_contents($f);
+ if (!empty($data)) {
+ list($storedId, $storedPassword, $sites) = unserialize($data);
+ if ($id === $storedId) {
+ if ($trusted === null) {
+ unset($sites[$site]);
+ } else {
+ $sites[$site] = $trusted;
+ }
+ rewind($f);
+ ftruncate($f, 0);
+ $data = serialize(array($id, $storedPassword, $sites));
+ fwrite($f, $data);
+ $ret = true;
+ }
+ }
+ fclose($f);
+ fclose($lock);
+ return $ret;
+ }
+}
diff --git a/applications/core/lib/Zend/OpenId/Provider/User.php b/applications/core/lib/Zend/OpenId/Provider/User.php
new file mode 100644
index 0000000..db73612
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Provider/User.php
@@ -0,0 +1,57 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Provider
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: User.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+/**
+ * Abstract class to get/store information about logged in user in Web Browser
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Provider
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_OpenId_Provider_User
+{
+
+ /**
+ * Stores information about logged in user
+ *
+ * @param string $id user identity URL
+ * @return bool
+ */
+ abstract public function setLoggedInUser($id);
+
+ /**
+ * Returns identity URL of logged in user or false
+ *
+ * @return mixed
+ */
+ abstract public function getLoggedInUser();
+
+ /**
+ * Performs logout. Clears information about logged in user.
+ *
+ * @return bool
+ */
+ abstract public function delLoggedInUser();
+}
diff --git a/applications/core/lib/Zend/OpenId/Provider/User/Session.php b/applications/core/lib/Zend/OpenId/Provider/User/Session.php
new file mode 100644
index 0000000..90870b0
--- /dev/null
+++ b/applications/core/lib/Zend/OpenId/Provider/User/Session.php
@@ -0,0 +1,104 @@
+<?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 [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Provider
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Session.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+/**
+ * @see Zend_OpenId_Provider_User
+ */
+require_once "Zend/OpenId/Provider/User.php";
+
+/**
+ * @see Zend_Session_Namespace
+ */
+require_once "Zend/Session/Namespace.php";
+
+/**
+ * Class to get/store information about logged in user in Web Browser using
+ * PHP session
+ *
+ * @category Zend
+ * @package Zend_OpenId
+ * @subpackage Zend_OpenId_Provider
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_OpenId_Provider_User_Session extends Zend_OpenId_Provider_User
+{
+ /**
+ * Reference to an implementation of Zend_Session_Namespace object
+ *
+ * @var Zend_Session_Namespace $_session
+ */
+ private $_session = null;
+
+ /**
+ * Creates Zend_OpenId_Provider_User_Session object with given session
+ * namespace or creates new session namespace named "openid"
+ *
+ * @param Zend_Session_Namespace $session
+ */
+ public function __construct(Zend_Session_Namespace $session = null)
+ {
+ if ($session === null) {
+ $this->_session = new Zend_Session_Namespace("openid");
+ } else {
+ $this->_session = $session;
+ }
+ }
+
+ /**
+ * Stores information about logged in user in session data
+ *
+ * @param string $id user identity URL
+ * @return bool
+ */
+ public function setLoggedInUser($id)
+ {
+ $this->_session->logged_in = $id;
+ return true;
+ }
+
+ /**
+ * Returns identity URL of logged in user or false
+ *
+ * @return mixed
+ */
+ public function getLoggedInUser()
+ {
+ if (isset($this->_session->logged_in)) {
+ return $this->_session->logged_in;
+ }
+ return false;
+ }
+
+ /**
+ * Performs logout. Clears information about logged in user.
+ *
+ * @return bool
+ */
+ public function delLoggedInUser()
+ {
+ unset($this->_session->logged_in);
+ return true;
+ }
+
+}