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

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

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