PageRenderTime 52ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/www/system/library/Zend/OpenId/Consumer/Storage/File.php

https://bitbucket.org/vmihailenco/zf-blog
PHP | 507 lines | 354 code | 19 blank | 134 comment | 60 complexity | ff2e810e8731f190869288a61751f6ac MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_OpenId
  17. * @subpackage Zend_OpenId_Consumer
  18. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: File.php 20096 2010-01-06 02:05:09Z bkarwin $
  21. */
  22. /**
  23. * @see Zend_OpenId_Consumer_Storage
  24. */
  25. /**
  26. * External storage implemmentation using serialized files
  27. *
  28. * @category Zend
  29. * @package Zend_OpenId
  30. * @subpackage Zend_OpenId_Consumer
  31. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  32. * @license http://framework.zend.com/license/new-bsd New BSD License
  33. */
  34. class Zend_OpenId_Consumer_Storage_File extends Zend_OpenId_Consumer_Storage
  35. {
  36. /**
  37. * Directory name to store data files in
  38. *
  39. * @var string $_dir
  40. */
  41. private $_dir;
  42. /**
  43. * Constructs storage object and creates storage directory
  44. *
  45. * @param string $dir directory name to store data files in
  46. * @throws Zend_OpenId_Exception
  47. */
  48. public function __construct($dir = null)
  49. {
  50. if ($dir === null) {
  51. $tmp = getenv('TMP');
  52. if (empty($tmp)) {
  53. $tmp = getenv('TEMP');
  54. if (empty($tmp)) {
  55. $tmp = "/tmp";
  56. }
  57. }
  58. $user = get_current_user();
  59. if (is_string($user) && !empty($user)) {
  60. $tmp .= '/' . $user;
  61. }
  62. $dir = $tmp . '/openid/consumer';
  63. }
  64. $this->_dir = $dir;
  65. if (!is_dir($this->_dir)) {
  66. if (!@mkdir($this->_dir, 0700, 1)) {
  67. /**
  68. * @see Zend_OpenId_Exception
  69. */
  70. throw new Zend_OpenId_Exception(
  71. 'Cannot access storage directory ' . $dir,
  72. Zend_OpenId_Exception::ERROR_STORAGE);
  73. }
  74. }
  75. if (($f = fopen($this->_dir.'/assoc.lock', 'w+')) === null) {
  76. /**
  77. * @see Zend_OpenId_Exception
  78. */
  79. throw new Zend_OpenId_Exception(
  80. 'Cannot create a lock file in the directory ' . $dir,
  81. Zend_OpenId_Exception::ERROR_STORAGE);
  82. }
  83. fclose($f);
  84. if (($f = fopen($this->_dir.'/discovery.lock', 'w+')) === null) {
  85. /**
  86. * @see Zend_OpenId_Exception
  87. */
  88. throw new Zend_OpenId_Exception(
  89. 'Cannot create a lock file in the directory ' . $dir,
  90. Zend_OpenId_Exception::ERROR_STORAGE);
  91. }
  92. fclose($f);
  93. if (($f = fopen($this->_dir.'/nonce.lock', 'w+')) === null) {
  94. /**
  95. * @see Zend_OpenId_Exception
  96. */
  97. throw new Zend_OpenId_Exception(
  98. 'Cannot create a lock file in the directory ' . $dir,
  99. Zend_OpenId_Exception::ERROR_STORAGE);
  100. }
  101. fclose($f);
  102. }
  103. /**
  104. * Stores information about association identified by $url/$handle
  105. *
  106. * @param string $url OpenID server URL
  107. * @param string $handle assiciation handle
  108. * @param string $macFunc HMAC function (sha1 or sha256)
  109. * @param string $secret shared secret
  110. * @param long $expires expiration UNIX time
  111. * @return bool
  112. */
  113. public function addAssociation($url, $handle, $macFunc, $secret, $expires)
  114. {
  115. $name1 = $this->_dir . '/assoc_url_' . md5($url);
  116. $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
  117. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  118. if ($lock === false) {
  119. return false;
  120. }
  121. if (!flock($lock, LOCK_EX)) {
  122. fclose($lock);
  123. return false;
  124. }
  125. try {
  126. $f = @fopen($name1, 'w+');
  127. if ($f === false) {
  128. fclose($lock);
  129. return false;
  130. }
  131. $data = serialize(array($url, $handle, $macFunc, $secret, $expires));
  132. fwrite($f, $data);
  133. if (function_exists('symlink')) {
  134. @unlink($name2);
  135. if (symlink($name1, $name2)) {
  136. fclose($f);
  137. fclose($lock);
  138. return true;
  139. }
  140. }
  141. $f2 = @fopen($name2, 'w+');
  142. if ($f2) {
  143. fwrite($f2, $data);
  144. fclose($f2);
  145. @unlink($name1);
  146. $ret = true;
  147. } else {
  148. $ret = false;
  149. }
  150. fclose($f);
  151. fclose($lock);
  152. return $ret;
  153. } catch (Exception $e) {
  154. fclose($lock);
  155. throw $e;
  156. }
  157. }
  158. /**
  159. * Gets information about association identified by $url
  160. * Returns true if given association found and not expired and false
  161. * otherwise
  162. *
  163. * @param string $url OpenID server URL
  164. * @param string &$handle assiciation handle
  165. * @param string &$macFunc HMAC function (sha1 or sha256)
  166. * @param string &$secret shared secret
  167. * @param long &$expires expiration UNIX time
  168. * @return bool
  169. */
  170. public function getAssociation($url, &$handle, &$macFunc, &$secret, &$expires)
  171. {
  172. $name1 = $this->_dir . '/assoc_url_' . md5($url);
  173. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  174. if ($lock === false) {
  175. return false;
  176. }
  177. if (!flock($lock, LOCK_EX)) {
  178. fclose($lock);
  179. return false;
  180. }
  181. try {
  182. $f = @fopen($name1, 'r');
  183. if ($f === false) {
  184. fclose($lock);
  185. return false;
  186. }
  187. $ret = false;
  188. $data = stream_get_contents($f);
  189. if (!empty($data)) {
  190. list($storedUrl, $handle, $macFunc, $secret, $expires) = unserialize($data);
  191. if ($url === $storedUrl && $expires > time()) {
  192. $ret = true;
  193. } else {
  194. $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
  195. fclose($f);
  196. @unlink($name2);
  197. @unlink($name1);
  198. fclose($lock);
  199. return false;
  200. }
  201. }
  202. fclose($f);
  203. fclose($lock);
  204. return $ret;
  205. } catch (Exception $e) {
  206. fclose($lock);
  207. throw $e;
  208. }
  209. }
  210. /**
  211. * Gets information about association identified by $handle
  212. * Returns true if given association found and not expired and false
  213. * otherwise
  214. *
  215. * @param string $handle assiciation handle
  216. * @param string &$url OpenID server URL
  217. * @param string &$macFunc HMAC function (sha1 or sha256)
  218. * @param string &$secret shared secret
  219. * @param long &$expires expiration UNIX time
  220. * @return bool
  221. */
  222. public function getAssociationByHandle($handle, &$url, &$macFunc, &$secret, &$expires)
  223. {
  224. $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
  225. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  226. if ($lock === false) {
  227. return false;
  228. }
  229. if (!flock($lock, LOCK_EX)) {
  230. fclose($lock);
  231. return false;
  232. }
  233. try {
  234. $f = @fopen($name2, 'r');
  235. if ($f === false) {
  236. fclose($lock);
  237. return false;
  238. }
  239. $ret = false;
  240. $data = stream_get_contents($f);
  241. if (!empty($data)) {
  242. list($url, $storedHandle, $macFunc, $secret, $expires) = unserialize($data);
  243. if ($handle === $storedHandle && $expires > time()) {
  244. $ret = true;
  245. } else {
  246. fclose($f);
  247. @unlink($name2);
  248. $name1 = $this->_dir . '/assoc_url_' . md5($url);
  249. @unlink($name1);
  250. fclose($lock);
  251. return false;
  252. }
  253. }
  254. fclose($f);
  255. fclose($lock);
  256. return $ret;
  257. } catch (Exception $e) {
  258. fclose($lock);
  259. throw $e;
  260. }
  261. }
  262. /**
  263. * Deletes association identified by $url
  264. *
  265. * @param string $url OpenID server URL
  266. * @return bool
  267. */
  268. public function delAssociation($url)
  269. {
  270. $name1 = $this->_dir . '/assoc_url_' . md5($url);
  271. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  272. if ($lock === false) {
  273. return false;
  274. }
  275. if (!flock($lock, LOCK_EX)) {
  276. fclose($lock);
  277. return false;
  278. }
  279. try {
  280. $f = @fopen($name1, 'r');
  281. if ($f === false) {
  282. fclose($lock);
  283. return false;
  284. }
  285. $data = stream_get_contents($f);
  286. if (!empty($data)) {
  287. list($storedUrl, $handle, $macFunc, $secret, $expires) = unserialize($data);
  288. if ($url === $storedUrl) {
  289. $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
  290. fclose($f);
  291. @unlink($name2);
  292. @unlink($name1);
  293. fclose($lock);
  294. return true;
  295. }
  296. }
  297. fclose($f);
  298. fclose($lock);
  299. return true;
  300. } catch (Exception $e) {
  301. fclose($lock);
  302. throw $e;
  303. }
  304. }
  305. /**
  306. * Stores information discovered from identity $id
  307. *
  308. * @param string $id identity
  309. * @param string $realId discovered real identity URL
  310. * @param string $server discovered OpenID server URL
  311. * @param float $version discovered OpenID protocol version
  312. * @param long $expires expiration UNIX time
  313. * @return bool
  314. */
  315. public function addDiscoveryInfo($id, $realId, $server, $version, $expires)
  316. {
  317. $name = $this->_dir . '/discovery_' . md5($id);
  318. $lock = @fopen($this->_dir . '/discovery.lock', 'w+');
  319. if ($lock === false) {
  320. return false;
  321. }
  322. if (!flock($lock, LOCK_EX)) {
  323. fclose($lock);
  324. return false;
  325. }
  326. try {
  327. $f = @fopen($name, 'w+');
  328. if ($f === false) {
  329. fclose($lock);
  330. return false;
  331. }
  332. $data = serialize(array($id, $realId, $server, $version, $expires));
  333. fwrite($f, $data);
  334. fclose($f);
  335. fclose($lock);
  336. return true;
  337. } catch (Exception $e) {
  338. fclose($lock);
  339. throw $e;
  340. }
  341. }
  342. /**
  343. * Gets information discovered from identity $id
  344. * Returns true if such information exists and false otherwise
  345. *
  346. * @param string $id identity
  347. * @param string &$realId discovered real identity URL
  348. * @param string &$server discovered OpenID server URL
  349. * @param float &$version discovered OpenID protocol version
  350. * @param long &$expires expiration UNIX time
  351. * @return bool
  352. */
  353. public function getDiscoveryInfo($id, &$realId, &$server, &$version, &$expires)
  354. {
  355. $name = $this->_dir . '/discovery_' . md5($id);
  356. $lock = @fopen($this->_dir . '/discovery.lock', 'w+');
  357. if ($lock === false) {
  358. return false;
  359. }
  360. if (!flock($lock, LOCK_EX)) {
  361. fclose($lock);
  362. return false;
  363. }
  364. try {
  365. $f = @fopen($name, 'r');
  366. if ($f === false) {
  367. fclose($lock);
  368. return false;
  369. }
  370. $ret = false;
  371. $data = stream_get_contents($f);
  372. if (!empty($data)) {
  373. list($storedId, $realId, $server, $version, $expires) = unserialize($data);
  374. if ($id === $storedId && $expires > time()) {
  375. $ret = true;
  376. } else {
  377. fclose($f);
  378. @unlink($name);
  379. fclose($lock);
  380. return false;
  381. }
  382. }
  383. fclose($f);
  384. fclose($lock);
  385. return $ret;
  386. } catch (Exception $e) {
  387. fclose($lock);
  388. throw $e;
  389. }
  390. }
  391. /**
  392. * Removes cached information discovered from identity $id
  393. *
  394. * @param string $id identity
  395. * @return bool
  396. */
  397. public function delDiscoveryInfo($id)
  398. {
  399. $name = $this->_dir . '/discovery_' . md5($id);
  400. $lock = @fopen($this->_dir . '/discovery.lock', 'w+');
  401. if ($lock === false) {
  402. return false;
  403. }
  404. if (!flock($lock, LOCK_EX)) {
  405. fclose($lock);
  406. return false;
  407. }
  408. try {
  409. @unlink($name);
  410. fclose($lock);
  411. return true;
  412. } catch (Exception $e) {
  413. fclose($lock);
  414. throw $e;
  415. }
  416. }
  417. /**
  418. * The function checks the uniqueness of openid.response_nonce
  419. *
  420. * @param string $provider openid.openid_op_endpoint field from authentication response
  421. * @param string $nonce openid.response_nonce field from authentication response
  422. * @return bool
  423. */
  424. public function isUniqueNonce($provider, $nonce)
  425. {
  426. $name = $this->_dir . '/nonce_' . md5($provider.';'.$nonce);
  427. $lock = @fopen($this->_dir . '/nonce.lock', 'w+');
  428. if ($lock === false) {
  429. return false;
  430. }
  431. if (!flock($lock, LOCK_EX)) {
  432. fclose($lock);
  433. return false;
  434. }
  435. try {
  436. $f = @fopen($name, 'x');
  437. if ($f === false) {
  438. fclose($lock);
  439. return false;
  440. }
  441. fwrite($f, $provider.';'.$nonce);
  442. fclose($f);
  443. fclose($lock);
  444. return true;
  445. } catch (Exception $e) {
  446. fclose($lock);
  447. throw $e;
  448. }
  449. }
  450. /**
  451. * Removes data from the uniqueness database that is older then given date
  452. *
  453. * @param mixed $date date of expired data
  454. */
  455. public function purgeNonces($date=null)
  456. {
  457. $lock = @fopen($this->_dir . '/nonce.lock', 'w+');
  458. if ($lock !== false) {
  459. flock($lock, LOCK_EX);
  460. }
  461. try {
  462. if (!is_int($date) && !is_string($date)) {
  463. foreach (glob($this->_dir . '/nonce_*') as $name) {
  464. @unlink($name);
  465. }
  466. } else {
  467. if (is_string($date)) {
  468. $time = time($date);
  469. } else {
  470. $time = $date;
  471. }
  472. foreach (glob($this->_dir . '/nonce_*') as $name) {
  473. if (filemtime($name) < $time) {
  474. @unlink($name);
  475. }
  476. }
  477. }
  478. if ($lock !== false) {
  479. fclose($lock);
  480. }
  481. } catch (Exception $e) {
  482. if ($lock !== false) {
  483. fclose($lock);
  484. }
  485. throw $e;
  486. }
  487. }
  488. }