File indexing completed on 2025-03-02 05:29:37
0001 <?php 0002 0003 /** 0004 * Zend Framework 0005 * 0006 * LICENSE 0007 * 0008 * This source file is subject to the new BSD license that is bundled 0009 * with this package in the file LICENSE.txt. 0010 * It is also available through the world-wide-web at this URL: 0011 * http://framework.zend.com/license/new-bsd 0012 * If you did not receive a copy of the license and are unable to 0013 * obtain it through the world-wide-web, please send an email 0014 * to license@zend.com so we can send you a copy immediately. 0015 * 0016 * @category Zend 0017 * @package Zend_OpenId 0018 * @subpackage Zend_OpenId_Provider 0019 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0020 * @license http://framework.zend.com/license/new-bsd New BSD License 0021 * @version $Id$ 0022 */ 0023 0024 /** 0025 * @see Zend_OpenId_Provider_Storage 0026 */ 0027 // require_once "Zend/OpenId/Provider/Storage.php"; 0028 0029 /** 0030 * External storage implemmentation using serialized files 0031 * 0032 * @category Zend 0033 * @package Zend_OpenId 0034 * @subpackage Zend_OpenId_Provider 0035 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0036 * @license http://framework.zend.com/license/new-bsd New BSD License 0037 */ 0038 class Zend_OpenId_Provider_Storage_File extends Zend_OpenId_Provider_Storage 0039 { 0040 0041 /** 0042 * Directory name to store data files in 0043 * 0044 * @var string $_dir 0045 */ 0046 private $_dir; 0047 0048 /** 0049 * Constructs storage object and creates storage directory 0050 * 0051 * @param string $dir directory name to store data files in 0052 * @throws Zend_OpenId_Exception 0053 */ 0054 public function __construct($dir = null) 0055 { 0056 if ($dir === null) { 0057 $tmp = getenv('TMP'); 0058 if (empty($tmp)) { 0059 $tmp = getenv('TEMP'); 0060 if (empty($tmp)) { 0061 $tmp = "/tmp"; 0062 } 0063 } 0064 $user = get_current_user(); 0065 if (is_string($user) && !empty($user)) { 0066 $tmp .= '/' . $user; 0067 } 0068 $dir = $tmp . '/openid/provider'; 0069 } 0070 $this->_dir = $dir; 0071 if (!is_dir($this->_dir)) { 0072 if (!@mkdir($this->_dir, 0700, 1)) { 0073 throw new Zend_OpenId_Exception( 0074 "Cannot access storage directory $dir", 0075 Zend_OpenId_Exception::ERROR_STORAGE); 0076 } 0077 } 0078 if (($f = fopen($this->_dir.'/assoc.lock', 'w+')) === null) { 0079 throw new Zend_OpenId_Exception( 0080 'Cannot create a lock file in the directory ' . $dir, 0081 Zend_OpenId_Exception::ERROR_STORAGE); 0082 } 0083 fclose($f); 0084 if (($f = fopen($this->_dir.'/user.lock', 'w+')) === null) { 0085 throw new Zend_OpenId_Exception( 0086 'Cannot create a lock file in the directory ' . $dir, 0087 Zend_OpenId_Exception::ERROR_STORAGE); 0088 } 0089 fclose($f); 0090 } 0091 0092 /** 0093 * Stores information about session identified by $handle 0094 * 0095 * @param string $handle assiciation handle 0096 * @param string $macFunc HMAC function (sha1 or sha256) 0097 * @param string $secret shared secret 0098 * @param string $expires expiration UNIX time 0099 * @return bool 0100 */ 0101 public function addAssociation($handle, $macFunc, $secret, $expires) 0102 { 0103 $name = $this->_dir . '/assoc_' . md5($handle); 0104 $lock = @fopen($this->_dir . '/assoc.lock', 'w+'); 0105 if ($lock === false) { 0106 return false; 0107 } 0108 if (!flock($lock, LOCK_EX)) { 0109 fclose($lock); 0110 return false; 0111 } 0112 try { 0113 $f = @fopen($name, 'w+'); 0114 if ($f === false) { 0115 fclose($lock); 0116 return false; 0117 } 0118 $data = serialize(array($handle, $macFunc, $secret, $expires)); 0119 fwrite($f, $data); 0120 fclose($f); 0121 fclose($lock); 0122 return true; 0123 } catch (Exception $e) { 0124 fclose($lock); 0125 throw $e; 0126 } 0127 } 0128 0129 /** 0130 * Gets information about association identified by $handle 0131 * Returns true if given association found and not expired and false 0132 * otherwise 0133 * 0134 * @param string $handle assiciation handle 0135 * @param string &$macFunc HMAC function (sha1 or sha256) 0136 * @param string &$secret shared secret 0137 * @param string &$expires expiration UNIX time 0138 * @return bool 0139 */ 0140 public function getAssociation($handle, &$macFunc, &$secret, &$expires) 0141 { 0142 $name = $this->_dir . '/assoc_' . md5($handle); 0143 $lock = @fopen($this->_dir . '/assoc.lock', 'w+'); 0144 if ($lock === false) { 0145 return false; 0146 } 0147 if (!flock($lock, LOCK_EX)) { 0148 fclose($lock); 0149 return false; 0150 } 0151 try { 0152 $f = @fopen($name, 'r'); 0153 if ($f === false) { 0154 fclose($lock); 0155 return false; 0156 } 0157 $ret = false; 0158 $data = stream_get_contents($f); 0159 if (!empty($data)) { 0160 list($storedHandle, $macFunc, $secret, $expires) = unserialize($data); 0161 if ($handle === $storedHandle && $expires > time()) { 0162 $ret = true; 0163 } else { 0164 fclose($f); 0165 @unlink($name); 0166 fclose($lock); 0167 return false; 0168 } 0169 } 0170 fclose($f); 0171 fclose($lock); 0172 return $ret; 0173 } catch (Exception $e) { 0174 fclose($lock); 0175 throw $e; 0176 } 0177 } 0178 0179 /** 0180 * Removes information about association identified by $handle 0181 * 0182 * @param string $handle assiciation handle 0183 * @return bool 0184 */ 0185 public function delAssociation($handle) 0186 { 0187 $name = $this->_dir . '/assoc_' . md5($handle); 0188 $lock = @fopen($this->_dir . '/assoc.lock', 'w+'); 0189 if ($lock === false) { 0190 return false; 0191 } 0192 if (!flock($lock, LOCK_EX)) { 0193 fclose($lock); 0194 return false; 0195 } 0196 try { 0197 @unlink($name); 0198 fclose($lock); 0199 return true; 0200 } catch (Exception $e) { 0201 fclose($lock); 0202 throw $e; 0203 } 0204 } 0205 0206 /** 0207 * Register new user with given $id and $password 0208 * Returns true in case of success and false if user with given $id already 0209 * exists 0210 * 0211 * @param string $id user identity URL 0212 * @param string $password encoded user password 0213 * @return bool 0214 */ 0215 public function addUser($id, $password) 0216 { 0217 $name = $this->_dir . '/user_' . md5($id); 0218 $lock = @fopen($this->_dir . '/user.lock', 'w+'); 0219 if ($lock === false) { 0220 return false; 0221 } 0222 if (!flock($lock, LOCK_EX)) { 0223 fclose($lock); 0224 return false; 0225 } 0226 try { 0227 $f = @fopen($name, 'x'); 0228 if ($f === false) { 0229 fclose($lock); 0230 return false; 0231 } 0232 $data = serialize(array($id, $password, array())); 0233 fwrite($f, $data); 0234 fclose($f); 0235 fclose($lock); 0236 return true; 0237 } catch (Exception $e) { 0238 fclose($lock); 0239 throw $e; 0240 } 0241 } 0242 0243 /** 0244 * Returns true if user with given $id exists and false otherwise 0245 * 0246 * @param string $id user identity URL 0247 * @return bool 0248 */ 0249 public function hasUser($id) 0250 { 0251 $name = $this->_dir . '/user_' . md5($id); 0252 $lock = @fopen($this->_dir . '/user.lock', 'w+'); 0253 if ($lock === false) { 0254 return false; 0255 } 0256 if (!flock($lock, LOCK_SH)) { 0257 fclose($lock); 0258 return false; 0259 } 0260 try { 0261 $f = @fopen($name, 'r'); 0262 if ($f === false) { 0263 fclose($lock); 0264 return false; 0265 } 0266 $ret = false; 0267 $data = stream_get_contents($f); 0268 if (!empty($data)) { 0269 list($storedId, $storedPassword, $trusted) = unserialize($data); 0270 if ($id === $storedId) { 0271 $ret = true; 0272 } 0273 } 0274 fclose($f); 0275 fclose($lock); 0276 return $ret; 0277 } catch (Exception $e) { 0278 fclose($lock); 0279 throw $e; 0280 } 0281 } 0282 0283 /** 0284 * Verify if user with given $id exists and has specified $password 0285 * 0286 * @param string $id user identity URL 0287 * @param string $password user password 0288 * @return bool 0289 */ 0290 public function checkUser($id, $password) 0291 { 0292 $name = $this->_dir . '/user_' . md5($id); 0293 $lock = @fopen($this->_dir . '/user.lock', 'w+'); 0294 if ($lock === false) { 0295 return false; 0296 } 0297 if (!flock($lock, LOCK_SH)) { 0298 fclose($lock); 0299 return false; 0300 } 0301 try { 0302 $f = @fopen($name, 'r'); 0303 if ($f === false) { 0304 fclose($lock); 0305 return false; 0306 } 0307 $ret = false; 0308 $data = stream_get_contents($f); 0309 if (!empty($data)) { 0310 list($storedId, $storedPassword, $trusted) = unserialize($data); 0311 if ($id === $storedId && $password === $storedPassword) { 0312 $ret = true; 0313 } 0314 } 0315 fclose($f); 0316 fclose($lock); 0317 return $ret; 0318 } catch (Exception $e) { 0319 fclose($lock); 0320 throw $e; 0321 } 0322 } 0323 0324 /** 0325 * Removes information abou specified user 0326 * 0327 * @param string $id user identity URL 0328 * @return bool 0329 */ 0330 public function delUser($id) 0331 { 0332 $name = $this->_dir . '/user_' . md5($id); 0333 $lock = @fopen($this->_dir . '/user.lock', 'w+'); 0334 if ($lock === false) { 0335 return false; 0336 } 0337 if (!flock($lock, LOCK_EX)) { 0338 fclose($lock); 0339 return false; 0340 } 0341 try { 0342 @unlink($name); 0343 fclose($lock); 0344 return true; 0345 } catch (Exception $e) { 0346 fclose($lock); 0347 throw $e; 0348 } 0349 } 0350 0351 /** 0352 * Returns array of all trusted/untrusted sites for given user identified 0353 * by $id 0354 * 0355 * @param string $id user identity URL 0356 * @return array 0357 */ 0358 public function getTrustedSites($id) 0359 { 0360 $name = $this->_dir . '/user_' . md5($id); 0361 $lock = @fopen($this->_dir . '/user.lock', 'w+'); 0362 if ($lock === false) { 0363 return false; 0364 } 0365 if (!flock($lock, LOCK_SH)) { 0366 fclose($lock); 0367 return false; 0368 } 0369 try { 0370 $f = @fopen($name, 'r'); 0371 if ($f === false) { 0372 fclose($lock); 0373 return false; 0374 } 0375 $ret = false; 0376 $data = stream_get_contents($f); 0377 if (!empty($data)) { 0378 list($storedId, $storedPassword, $trusted) = unserialize($data); 0379 if ($id === $storedId) { 0380 $ret = $trusted; 0381 } 0382 } 0383 fclose($f); 0384 fclose($lock); 0385 return $ret; 0386 } catch (Exception $e) { 0387 fclose($lock); 0388 throw $e; 0389 } 0390 } 0391 0392 /** 0393 * Stores information about trusted/untrusted site for given user 0394 * 0395 * @param string $id user identity URL 0396 * @param string $site site URL 0397 * @param mixed $trusted trust data from extension or just a boolean value 0398 * @return bool 0399 */ 0400 public function addSite($id, $site, $trusted) 0401 { 0402 $name = $this->_dir . '/user_' . md5($id); 0403 $lock = @fopen($this->_dir . '/user.lock', 'w+'); 0404 if ($lock === false) { 0405 return false; 0406 } 0407 if (!flock($lock, LOCK_EX)) { 0408 fclose($lock); 0409 return false; 0410 } 0411 try { 0412 $f = @fopen($name, 'r+'); 0413 if ($f === false) { 0414 fclose($lock); 0415 return false; 0416 } 0417 $ret = false; 0418 $data = stream_get_contents($f); 0419 if (!empty($data)) { 0420 list($storedId, $storedPassword, $sites) = unserialize($data); 0421 if ($id === $storedId) { 0422 if ($trusted === null) { 0423 unset($sites[$site]); 0424 } else { 0425 $sites[$site] = $trusted; 0426 } 0427 rewind($f); 0428 ftruncate($f, 0); 0429 $data = serialize(array($id, $storedPassword, $sites)); 0430 fwrite($f, $data); 0431 $ret = true; 0432 } 0433 } 0434 fclose($f); 0435 fclose($lock); 0436 return $ret; 0437 } catch (Exception $e) { 0438 fclose($lock); 0439 throw $e; 0440 } 0441 } 0442 }