PageRenderTime 54ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/app/lib/core/Zend/OpenId/Consumer/Storage/File.php

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