diff -r 5b37998e522e -r 162c1de6545a web/lib/Zend/OpenId/Consumer/Storage/File.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/Zend/OpenId/Consumer/Storage/File.php Fri Mar 11 15:05:35 2011 +0100 @@ -0,0 +1,511 @@ +_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; + } + try { + $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; + } catch (Exception $e) { + fclose($lock); + throw $e; + } + } + + /** + * 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; + } + try { + $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; + } catch (Exception $e) { + fclose($lock); + throw $e; + } + } + + /** + * 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; + } + try { + $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; + } catch (Exception $e) { + fclose($lock); + throw $e; + } + } + + /** + * 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; + } + try { + $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; + } catch (Exception $e) { + fclose($lock); + throw $e; + } + } + + /** + * 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; + } + try { + $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; + } catch (Exception $e) { + fclose($lock); + throw $e; + } + } + + /** + * 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; + } + try { + $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; + } catch (Exception $e) { + fclose($lock); + throw $e; + } + } + + /** + * 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; + } + try { + @unlink($name); + fclose($lock); + return true; + } catch (Exception $e) { + fclose($lock); + throw $e; + } + } + + /** + * 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; + } + try { + $f = @fopen($name, 'x'); + if ($f === false) { + fclose($lock); + return false; + } + fwrite($f, $provider.';'.$nonce); + fclose($f); + fclose($lock); + return true; + } catch (Exception $e) { + fclose($lock); + throw $e; + } + } + + /** + * 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); + } + try { + if (!is_int($date) && !is_string($date)) { + $nonceFiles = glob($this->_dir . '/nonce_*'); + foreach ((array) $nonceFiles as $name) { + @unlink($name); + } + unset($nonceFiles); + } else { + if (is_string($date)) { + $time = time($date); + } else { + $time = $date; + } + $nonceFiles = glob($this->_dir . '/nonce_*'); + foreach ((array) $nonceFiles as $name) { + if (filemtime($name) < $time) { + @unlink($name); + } + } + unset($nonceFiles); + } + if ($lock !== false) { + fclose($lock); + } + } catch (Exception $e) { + if ($lock !== false) { + fclose($lock); + } + throw $e; + } + } +}