PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/jverkoey/snaapilookup
PHP | 460 lines | 312 code | 14 blank | 134 comment | 59 complexity | 1221ee7a9e38a667b15cb1ee9cc1f765 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-2008 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 12970 2008-12-01 12:55:17Z dmitry $
  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-2008 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 (is_null($dir)) {
  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. $f = @fopen($name1, 'w+');
  131. if ($f === false) {
  132. fclose($lock);
  133. return false;
  134. }
  135. $data = serialize(array($url, $handle, $macFunc, $secret, $expires));
  136. fwrite($f, $data);
  137. if (function_exists('symlink')) {
  138. @unlink($name2);
  139. if (symlink($name1, $name2)) {
  140. fclose($f);
  141. fclose($lock);
  142. return true;
  143. }
  144. }
  145. $f2 = @fopen($name2, 'w+');
  146. if ($f2) {
  147. fwrite($f2, $data);
  148. fclose($f2);
  149. @unlink($name1);
  150. $ret = true;
  151. } else {
  152. $ret = false;
  153. }
  154. fclose($f);
  155. fclose($lock);
  156. return $ret;
  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. $f = @fopen($name1, 'r');
  182. if ($f === false) {
  183. fclose($lock);
  184. return false;
  185. }
  186. $ret = false;
  187. $data = stream_get_contents($f);
  188. if (!empty($data)) {
  189. list($storedUrl, $handle, $macFunc, $secret, $expires) = unserialize($data);
  190. if ($url === $storedUrl && $expires > time()) {
  191. $ret = true;
  192. } else {
  193. $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
  194. fclose($f);
  195. @unlink($name2);
  196. @unlink($name1);
  197. fclose($lock);
  198. return false;
  199. }
  200. }
  201. fclose($f);
  202. fclose($lock);
  203. return $ret;
  204. }
  205. /**
  206. * Gets information about association identified by $handle
  207. * Returns true if given association found and not expired and false
  208. * otherwise
  209. *
  210. * @param string $handle assiciation handle
  211. * @param string &$url OpenID server URL
  212. * @param string &$macFunc HMAC function (sha1 or sha256)
  213. * @param string &$secret shared secret
  214. * @param long &$expires expiration UNIX time
  215. * @return bool
  216. */
  217. public function getAssociationByHandle($handle, &$url, &$macFunc, &$secret, &$expires)
  218. {
  219. $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
  220. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  221. if ($lock === false) {
  222. return false;
  223. }
  224. if (!flock($lock, LOCK_EX)) {
  225. fclose($lock);
  226. return false;
  227. }
  228. $f = @fopen($name2, 'r');
  229. if ($f === false) {
  230. fclose($lock);
  231. return false;
  232. }
  233. $ret = false;
  234. $data = stream_get_contents($f);
  235. if (!empty($data)) {
  236. list($url, $storedHandle, $macFunc, $secret, $expires) = unserialize($data);
  237. if ($handle === $storedHandle && $expires > time()) {
  238. $ret = true;
  239. } else {
  240. fclose($f);
  241. @unlink($name2);
  242. $name1 = $this->_dir . '/assoc_url_' . md5($url);
  243. @unlink($name1);
  244. fclose($lock);
  245. return false;
  246. }
  247. }
  248. fclose($f);
  249. fclose($lock);
  250. return $ret;
  251. }
  252. /**
  253. * Deletes association identified by $url
  254. *
  255. * @param string $url OpenID server URL
  256. * @return bool
  257. */
  258. public function delAssociation($url)
  259. {
  260. $name1 = $this->_dir . '/assoc_url_' . md5($url);
  261. $lock = @fopen($this->_dir . '/assoc.lock', 'w+');
  262. if ($lock === false) {
  263. return false;
  264. }
  265. if (!flock($lock, LOCK_EX)) {
  266. fclose($lock);
  267. return false;
  268. }
  269. $f = @fopen($name1, 'r');
  270. if ($f === false) {
  271. fclose($lock);
  272. return false;
  273. }
  274. $data = stream_get_contents($f);
  275. if (!empty($data)) {
  276. list($storedUrl, $handle, $macFunc, $secret, $expires) = unserialize($data);
  277. if ($url === $storedUrl) {
  278. $name2 = $this->_dir . '/assoc_handle_' . md5($handle);
  279. fclose($f);
  280. @unlink($name2);
  281. @unlink($name1);
  282. fclose($lock);
  283. return true;
  284. }
  285. }
  286. fclose($f);
  287. fclose($lock);
  288. return true;
  289. }
  290. /**
  291. * Stores information discovered from identity $id
  292. *
  293. * @param string $id identity
  294. * @param string $realId discovered real identity URL
  295. * @param string $server discovered OpenID server URL
  296. * @param float $version discovered OpenID protocol version
  297. * @param long $expires expiration UNIX time
  298. * @return bool
  299. */
  300. public function addDiscoveryInfo($id, $realId, $server, $version, $expires)
  301. {
  302. $name = $this->_dir . '/discovery_' . md5($id);
  303. $lock = @fopen($this->_dir . '/discovery.lock', 'w+');
  304. if ($lock === false) {
  305. return false;
  306. }
  307. if (!flock($lock, LOCK_EX)) {
  308. fclose($lock);
  309. return false;
  310. }
  311. $f = @fopen($name, 'w+');
  312. if ($f === false) {
  313. fclose($lock);
  314. return false;
  315. }
  316. $data = serialize(array($id, $realId, $server, $version, $expires));
  317. fwrite($f, $data);
  318. fclose($f);
  319. fclose($lock);
  320. return true;
  321. }
  322. /**
  323. * Gets information discovered from identity $id
  324. * Returns true if such information exists and false otherwise
  325. *
  326. * @param string $id identity
  327. * @param string &$realId discovered real identity URL
  328. * @param string &$server discovered OpenID server URL
  329. * @param float &$version discovered OpenID protocol version
  330. * @param long &$expires expiration UNIX time
  331. * @return bool
  332. */
  333. public function getDiscoveryInfo($id, &$realId, &$server, &$version, &$expires)
  334. {
  335. $name = $this->_dir . '/discovery_' . md5($id);
  336. $lock = @fopen($this->_dir . '/discovery.lock', 'w+');
  337. if ($lock === false) {
  338. return false;
  339. }
  340. if (!flock($lock, LOCK_EX)) {
  341. fclose($lock);
  342. return false;
  343. }
  344. $f = @fopen($name, 'r');
  345. if ($f === false) {
  346. fclose($lock);
  347. return false;
  348. }
  349. $ret = false;
  350. $data = stream_get_contents($f);
  351. if (!empty($data)) {
  352. list($storedId, $realId, $server, $version, $expires) = unserialize($data);
  353. if ($id === $storedId && $expires > time()) {
  354. $ret = true;
  355. } else {
  356. fclose($f);
  357. @unlink($name);
  358. fclose($lock);
  359. return false;
  360. }
  361. }
  362. fclose($f);
  363. fclose($lock);
  364. return $ret;
  365. }
  366. /**
  367. * Removes cached information discovered from identity $id
  368. *
  369. * @param string $id identity
  370. * @return bool
  371. */
  372. public function delDiscoveryInfo($id)
  373. {
  374. $name = $this->_dir . '/discovery_' . md5($id);
  375. $lock = @fopen($this->_dir . '/discovery.lock', 'w+');
  376. if ($lock === false) {
  377. return false;
  378. }
  379. if (!flock($lock, LOCK_EX)) {
  380. fclose($lock);
  381. return false;
  382. }
  383. @unlink($name);
  384. fclose($lock);
  385. return true;
  386. }
  387. /**
  388. * The function checks the uniqueness of openid.response_nonce
  389. *
  390. * @param string $provider openid.openid_op_endpoint field from authentication response
  391. * @param string $nonce openid.response_nonce field from authentication response
  392. * @return bool
  393. */
  394. public function isUniqueNonce($provider, $nonce)
  395. {
  396. $name = $this->_dir . '/nonce_' . md5($provider.';'.$nonce);
  397. $lock = @fopen($this->_dir . '/nonce.lock', 'w+');
  398. if ($lock === false) {
  399. return false;
  400. }
  401. if (!flock($lock, LOCK_EX)) {
  402. fclose($lock);
  403. return false;
  404. }
  405. $f = @fopen($name, 'x');
  406. if ($f === false) {
  407. fclose($lock);
  408. return false;
  409. }
  410. fwrite($f, $provider.';'.$nonce);
  411. fclose($f);
  412. fclose($lock);
  413. return true;
  414. }
  415. /**
  416. * Removes data from the uniqueness database that is older then given date
  417. *
  418. * @param mixed $date date of expired data
  419. */
  420. public function purgeNonces($date=null)
  421. {
  422. $lock = @fopen($this->_dir . '/nonce.lock', 'w+');
  423. if ($lock !== false) {
  424. flock($lock, LOCK_EX);
  425. }
  426. if (!is_int($date) && !is_string($date)) {
  427. foreach (glob($this->_dir . '/nonce_*') as $name) {
  428. @unlink($name);
  429. }
  430. } else {
  431. if (is_string($date)) {
  432. $time = time($date);
  433. } else {
  434. $time = $date;
  435. }
  436. foreach (glob($this->_dir . '/nonce_*') as $name) {
  437. if (filemtime($name) < $time) {
  438. @unlink($name);
  439. }
  440. }
  441. }
  442. if ($lock !== false) {
  443. fclose($lock);
  444. }
  445. }
  446. }