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

/classes/Cookie.php

https://gitlab.com/staging06/myproject
PHP | 429 lines | 261 code | 42 blank | 126 comment | 54 complexity | 26674bdbab186735b960db2bb8cbc33b MD5 | raw file
  1. <?php
  2. /*
  3. * 2007-2015 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  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@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2015 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. class CookieCore
  27. {
  28. /** @var array Contain cookie content in a key => value format */
  29. protected $_content;
  30. /** @var array Crypted cookie name for setcookie() */
  31. protected $_name;
  32. /** @var array expiration date for setcookie() */
  33. protected $_expire;
  34. /** @var array Website domain for setcookie() */
  35. protected $_domain;
  36. /** @var array Path for setcookie() */
  37. protected $_path;
  38. /** @var array cipher tool instance */
  39. protected $_cipherTool;
  40. protected $_modified = false;
  41. protected $_allow_writing;
  42. protected $_salt;
  43. protected $_standalone;
  44. protected $_secure = false;
  45. /**
  46. * Get data if the cookie exists and else initialize an new one
  47. *
  48. * @param $name string Cookie name before encrypting
  49. * @param $path string
  50. */
  51. public function __construct($name, $path = '', $expire = null, $shared_urls = null, $standalone = false, $secure = false)
  52. {
  53. $this->_content = array();
  54. $this->_standalone = $standalone;
  55. $this->_expire = is_null($expire) ? time() + 1728000 : (int)$expire;
  56. $this->_path = trim(($this->_standalone ? '' : Context::getContext()->shop->physical_uri).$path, '/\\').'/';
  57. if ($this->_path{0} != '/') {
  58. $this->_path = '/'.$this->_path;
  59. }
  60. $this->_path = rawurlencode($this->_path);
  61. $this->_path = str_replace('%2F', '/', $this->_path);
  62. $this->_path = str_replace('%7E', '~', $this->_path);
  63. $this->_domain = $this->getDomain($shared_urls);
  64. $this->_name = 'PrestaShop-'.md5(($this->_standalone ? '' : _PS_VERSION_).$name.$this->_domain);
  65. $this->_allow_writing = true;
  66. $this->_salt = $this->_standalone ? str_pad('', 8, md5('ps'.__FILE__)) : _COOKIE_IV_;
  67. if ($this->_standalone) {
  68. $this->_cipherTool = new Blowfish(str_pad('', 56, md5('ps'.__FILE__)), str_pad('', 56, md5('iv'.__FILE__)));
  69. } elseif (!Configuration::get('PS_CIPHER_ALGORITHM') || !defined('_RIJNDAEL_KEY_')) {
  70. $this->_cipherTool = new Blowfish(_COOKIE_KEY_, _COOKIE_IV_);
  71. } else {
  72. $this->_cipherTool = new Rijndael(_RIJNDAEL_KEY_, _RIJNDAEL_IV_);
  73. }
  74. $this->_secure = (bool)$secure;
  75. $this->update();
  76. }
  77. public function disallowWriting()
  78. {
  79. $this->_allow_writing = false;
  80. }
  81. protected function getDomain($shared_urls = null)
  82. {
  83. $r = '!(?:(\w+)://)?(?:(\w+)\:(\w+)@)?([^/:]+)?(?:\:(\d*))?([^#?]+)?(?:\?([^#]+))?(?:#(.+$))?!i';
  84. if (!preg_match($r, Tools::getHttpHost(false, false), $out) || !isset($out[4])) {
  85. return false;
  86. }
  87. if (preg_match('/^(((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]{1}[0-9]|[1-9]).)'.
  88. '{1}((25[0-5]|2[0-4][0-9]|[1]{1}[0-9]{2}|[1-9]{1}[0-9]|[0-9]).)'.
  89. '{2}((25[0-5]|2[0-4][0-9]|[1]{1}[0-9]{2}|[1-9]{1}[0-9]|[0-9]){1}))$/', $out[4])) {
  90. return false;
  91. }
  92. if (!strstr(Tools::getHttpHost(false, false), '.')) {
  93. return false;
  94. }
  95. $domain = false;
  96. if ($shared_urls !== null) {
  97. foreach ($shared_urls as $shared_url) {
  98. if ($shared_url != $out[4]) {
  99. continue;
  100. }
  101. if (preg_match('/^(?:.*\.)?([^.]*(?:.{2,4})?\..{2,3})$/Ui', $shared_url, $res)) {
  102. $domain = '.'.$res[1];
  103. break;
  104. }
  105. }
  106. }
  107. if (!$domain) {
  108. $domain = $out[4];
  109. }
  110. return $domain;
  111. }
  112. /**
  113. * Set expiration date
  114. *
  115. * @param int $expire Expiration time from now
  116. */
  117. public function setExpire($expire)
  118. {
  119. $this->_expire = (int)($expire);
  120. }
  121. /**
  122. * Magic method wich return cookie data from _content array
  123. *
  124. * @param string $key key wanted
  125. * @return string value corresponding to the key
  126. */
  127. public function __get($key)
  128. {
  129. return isset($this->_content[$key]) ? $this->_content[$key] : false;
  130. }
  131. /**
  132. * Magic method which check if key exists in the cookie
  133. *
  134. * @param string $key key wanted
  135. * @return bool key existence
  136. */
  137. public function __isset($key)
  138. {
  139. return isset($this->_content[$key]);
  140. }
  141. /**
  142. * Magic method which adds data into _content array
  143. *
  144. * @param string $key Access key for the value
  145. * @param mixed $value Value corresponding to the key
  146. * @throws Exception
  147. */
  148. public function __set($key, $value)
  149. {
  150. if (is_array($value)) {
  151. die(Tools::displayError());
  152. }
  153. if (preg_match('/¤|\|/', $key.$value)) {
  154. throw new Exception('Forbidden chars in cookie');
  155. }
  156. if (!$this->_modified && (!isset($this->_content[$key]) || (isset($this->_content[$key]) && $this->_content[$key] != $value))) {
  157. $this->_modified = true;
  158. }
  159. $this->_content[$key] = $value;
  160. }
  161. /**
  162. * Magic method wich delete data into _content array
  163. *
  164. * @param string $key key wanted
  165. */
  166. public function __unset($key)
  167. {
  168. if (isset($this->_content[$key])) {
  169. $this->_modified = true;
  170. }
  171. unset($this->_content[$key]);
  172. }
  173. /**
  174. * Check customer informations saved into cookie and return customer validity
  175. *
  176. * @deprecated as of version 1.5 use Customer::isLogged() instead
  177. * @return bool customer validity
  178. */
  179. public function isLogged($withGuest = false)
  180. {
  181. Tools::displayAsDeprecated();
  182. if (!$withGuest && $this->is_guest == 1) {
  183. return false;
  184. }
  185. /* Customer is valid only if it can be load and if cookie password is the same as database one */
  186. if ($this->logged == 1 && $this->id_customer && Validate::isUnsignedId($this->id_customer) && Customer::checkPassword((int)($this->id_customer), $this->passwd)) {
  187. return true;
  188. }
  189. return false;
  190. }
  191. /**
  192. * Check employee informations saved into cookie and return employee validity
  193. *
  194. * @deprecated as of version 1.5 use Employee::isLoggedBack() instead
  195. * @return bool employee validity
  196. */
  197. public function isLoggedBack()
  198. {
  199. Tools::displayAsDeprecated();
  200. /* Employee is valid only if it can be load and if cookie password is the same as database one */
  201. return ($this->id_employee
  202. && Validate::isUnsignedId($this->id_employee)
  203. && Employee::checkPassword((int)$this->id_employee, $this->passwd)
  204. && (!isset($this->_content['remote_addr']) || $this->_content['remote_addr'] == ip2long(Tools::getRemoteAddr()) || !Configuration::get('PS_COOKIE_CHECKIP'))
  205. );
  206. }
  207. /**
  208. * Delete cookie
  209. * As of version 1.5 don't call this function, use Customer::logout() or Employee::logout() instead;
  210. */
  211. public function logout()
  212. {
  213. $this->_content = array();
  214. $this->_setcookie();
  215. unset($_COOKIE[$this->_name]);
  216. $this->_modified = true;
  217. }
  218. /**
  219. * Soft logout, delete everything links to the customer
  220. * but leave there affiliate's informations.
  221. * As of version 1.5 don't call this function, use Customer::mylogout() instead;
  222. */
  223. public function mylogout()
  224. {
  225. unset($this->_content['id_compare']);
  226. unset($this->_content['id_customer']);
  227. unset($this->_content['id_guest']);
  228. unset($this->_content['is_guest']);
  229. unset($this->_content['id_connections']);
  230. unset($this->_content['customer_lastname']);
  231. unset($this->_content['customer_firstname']);
  232. unset($this->_content['passwd']);
  233. unset($this->_content['logged']);
  234. unset($this->_content['email']);
  235. unset($this->_content['id_cart']);
  236. unset($this->_content['id_address_invoice']);
  237. unset($this->_content['id_address_delivery']);
  238. $this->_modified = true;
  239. }
  240. public function makeNewLog()
  241. {
  242. unset($this->_content['id_customer']);
  243. unset($this->_content['id_guest']);
  244. Guest::setNewGuest($this);
  245. $this->_modified = true;
  246. }
  247. /**
  248. * Get cookie content
  249. */
  250. public function update($nullValues = false)
  251. {
  252. if (isset($_COOKIE[$this->_name])) {
  253. /* Decrypt cookie content */
  254. $content = $this->_cipherTool->decrypt($_COOKIE[$this->_name]);
  255. //printf("\$content = %s<br />", $content);
  256. /* Get cookie checksum */
  257. $tmpTab = explode('¤', $content);
  258. array_pop($tmpTab);
  259. $content_for_checksum = implode('¤', $tmpTab).'¤';
  260. $checksum = crc32($this->_salt.$content_for_checksum);
  261. //printf("\$checksum = %s<br />", $checksum);
  262. /* Unserialize cookie content */
  263. $tmpTab = explode('¤', $content);
  264. foreach ($tmpTab as $keyAndValue) {
  265. $tmpTab2 = explode('|', $keyAndValue);
  266. if (count($tmpTab2) == 2) {
  267. $this->_content[$tmpTab2[0]] = $tmpTab2[1];
  268. }
  269. }
  270. /* Blowfish fix */
  271. if (isset($this->_content['checksum'])) {
  272. $this->_content['checksum'] = (int)($this->_content['checksum']);
  273. }
  274. //printf("\$this->_content['checksum'] = %s<br />", $this->_content['checksum']);
  275. //die();
  276. /* Check if cookie has not been modified */
  277. if (!isset($this->_content['checksum']) || $this->_content['checksum'] != $checksum) {
  278. $this->logout();
  279. }
  280. if (!isset($this->_content['date_add'])) {
  281. $this->_content['date_add'] = date('Y-m-d H:i:s');
  282. }
  283. } else {
  284. $this->_content['date_add'] = date('Y-m-d H:i:s');
  285. }
  286. //checks if the language exists, if not choose the default language
  287. if (!$this->_standalone && !Language::getLanguage((int)$this->id_lang)) {
  288. $this->id_lang = Configuration::get('PS_LANG_DEFAULT');
  289. // set detect_language to force going through Tools::setCookieLanguage to figure out browser lang
  290. $this->detect_language = true;
  291. }
  292. }
  293. /**
  294. * Setcookie according to php version
  295. */
  296. protected function _setcookie($cookie = null)
  297. {
  298. if ($cookie) {
  299. $content = $this->_cipherTool->encrypt($cookie);
  300. $time = $this->_expire;
  301. } else {
  302. $content = 0;
  303. $time = 1;
  304. }
  305. if (PHP_VERSION_ID <= 50200) { /* PHP version > 5.2.0 */
  306. return setcookie($this->_name, $content, $time, $this->_path, $this->_domain, $this->_secure);
  307. } else {
  308. return setcookie($this->_name, $content, $time, $this->_path, $this->_domain, $this->_secure, true);
  309. }
  310. }
  311. public function __destruct()
  312. {
  313. $this->write();
  314. }
  315. /**
  316. * Save cookie with setcookie()
  317. */
  318. public function write()
  319. {
  320. if (!$this->_modified || headers_sent() || !$this->_allow_writing) {
  321. return;
  322. }
  323. $cookie = '';
  324. /* Serialize cookie content */
  325. if (isset($this->_content['checksum'])) {
  326. unset($this->_content['checksum']);
  327. }
  328. foreach ($this->_content as $key => $value) {
  329. $cookie .= $key.'|'.$value.'¤';
  330. }
  331. /* Add checksum to cookie */
  332. $cookie .= 'checksum|'.crc32($this->_salt.$cookie);
  333. $this->_modified = false;
  334. /* Cookies are encrypted for evident security reasons */
  335. return $this->_setcookie($cookie);
  336. }
  337. /**
  338. * Get a family of variables (e.g. "filter_")
  339. */
  340. public function getFamily($origin)
  341. {
  342. $result = array();
  343. if (count($this->_content) == 0) {
  344. return $result;
  345. }
  346. foreach ($this->_content as $key => $value) {
  347. if (strncmp($key, $origin, strlen($origin)) == 0) {
  348. $result[$key] = $value;
  349. }
  350. }
  351. return $result;
  352. }
  353. /**
  354. *
  355. */
  356. public function unsetFamily($origin)
  357. {
  358. $family = $this->getFamily($origin);
  359. foreach (array_keys($family) as $member) {
  360. unset($this->$member);
  361. }
  362. }
  363. public function getAll()
  364. {
  365. return $this->_content;
  366. }
  367. /**
  368. * @return String name of cookie
  369. */
  370. public function getName()
  371. {
  372. return $this->_name;
  373. }
  374. /**
  375. * Check if the cookie exists
  376. *
  377. * @since 1.5.0
  378. * @return bool
  379. */
  380. public function exists()
  381. {
  382. return isset($_COOKIE[$this->_name]);
  383. }
  384. }