PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/phpSec/Common/Session.php

http://github.com/phpsec/phpSec
PHP | 238 lines | 129 code | 30 blank | 79 comment | 13 complexity | 75a55605c25334bd9a85bb2679dd69e5 MD5 | raw file
  1. <?php namespace phpSec\Common;
  2. /**
  3. phpSec - A PHP security library
  4. @author Audun Larsen <larsen@xqus.com>
  5. @copyright Copyright (c) Audun Larsen, 2011
  6. @link https://github.com/phpsec/phpSec
  7. @license http://opensource.org/licenses/mit-license.php The MIT License
  8. @package phpSec
  9. */
  10. class Session {
  11. /**
  12. * phpSec core Pimple container.
  13. */
  14. private $psl = null;
  15. private $sessIdRegen;
  16. private $savePath;
  17. private $name;
  18. private $keyCookie;
  19. private $secret;
  20. private $currID;
  21. private $newID;
  22. public $cryptAlgo = 'rijndael-256';
  23. public $cryptMode = 'cfb';
  24. /**
  25. * Constructor.
  26. *
  27. * @param \phpSec\Core $psl
  28. * phpSec core Pimple container.
  29. */
  30. public function __construct($psl) {
  31. $this->psl = $psl;
  32. ini_set('session.save_handler', 'user');
  33. session_set_save_handler(
  34. array($this, 'open'),
  35. array($this, 'close'),
  36. array($this, 'read'),
  37. array($this, 'write'),
  38. array($this, 'destroy'),
  39. array($this, 'gc')
  40. );
  41. /* Since we set a session cookie on our session handler, disable the built-in cookies. */
  42. ini_set('session.use_cookies', 0);
  43. }
  44. /**
  45. * Start session.
  46. *
  47. * @param bool $regen
  48. * Regenerate session ID or not.
  49. */
  50. public function start($regen = true) {
  51. $this->sessIdRegen = $regen;
  52. /* Start a new session. */
  53. session_start();
  54. /* Set UID. */
  55. $this->psl->getUid();
  56. }
  57. /**
  58. * Close a session.
  59. *
  60. * @return bool
  61. */
  62. public function close() {
  63. return true;
  64. }
  65. /**
  66. * Destroy/remove a session.
  67. *
  68. * @param string $id
  69. * @return bool
  70. */
  71. public function destroy($id) {
  72. $store = $this->psl['store'];
  73. return $store->delete('session', $id);
  74. }
  75. /**
  76. * Do garbage collection.
  77. *
  78. * @param integer $ttl
  79. * @return bool
  80. */
  81. public function gc($ttl) {
  82. $store = $this->psl['store'];
  83. $Ids = $store->listIds('session');
  84. foreach($Ids as $Id) {
  85. $data = $store->meta('session', $Id);
  86. if($data->time + $ttl < time()) {
  87. $store->delete('session', $Id);
  88. }
  89. }
  90. return true;
  91. }
  92. /**
  93. * Open a session.
  94. *
  95. * @param string $path
  96. * @param string $name
  97. * @return bool
  98. */
  99. public function open($path, $name) {
  100. $rand = $this->psl['crypt/rand'];
  101. /* Set some variables we need later. */
  102. $this->savePath = $path;
  103. $this->name = $name;
  104. $this->keyCookie = $name.'_secret';
  105. /* Set current and new ID. */
  106. if(isset($_COOKIE[$name])) {
  107. $this->currID = $_COOKIE[$name];
  108. } else {
  109. $this->currID = null;
  110. }
  111. if($this->sessIdRegen === true || $this->currID === null) {
  112. $this->newID = $rand->str(128, 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.!*#=%');
  113. } else {
  114. $this->newID = $this->currID;
  115. }
  116. /* Set cookie with new session ID. */
  117. $cookieParam = session_get_cookie_params();
  118. setcookie(
  119. $name,
  120. $this->newID,
  121. $cookieParam['lifetime'],
  122. $cookieParam['path'],
  123. $cookieParam['domain'],
  124. $cookieParam['secure'],
  125. $cookieParam['httponly']
  126. );
  127. /* If we don't have a encryption key, create one. */
  128. if(!isset($_COOKIE[$this->keyCookie])) {
  129. /* Create a secret used for encryption of session. */
  130. $this->setSecret();
  131. } else {
  132. $this->secret = base64_decode($_COOKIE[$this->keyCookie]);
  133. }
  134. return true;
  135. }
  136. /**
  137. * Read and decrypt a session.
  138. *
  139. * @param string $id
  140. * @return mixed
  141. */
  142. public function read($id) {
  143. $crypto = $this->psl['crypt/crypto'];
  144. $store = $this->psl['store'];
  145. /* If no cookie is set, just drop it! */
  146. if(!isset($_COOKIE[$this->name])) {
  147. return false;
  148. }
  149. /* Read from store and decrypt. */
  150. try {
  151. $sessData = $store->read('session', $_COOKIE[$this->name]);
  152. if($sessData !== false ) {
  153. $return = $crypto->decrypt($sessData, $this->secret);
  154. } else {
  155. $return = false;
  156. }
  157. return $return;
  158. } catch (\phpSec\Exception $e) {
  159. return false;
  160. }
  161. }
  162. /**
  163. * Encrypt and save a session.
  164. *
  165. * @param string $id
  166. * @param string $data
  167. * @return bool
  168. */
  169. public function write($id , $data) {
  170. $crypto = $this->psl['crypt/crypto'];
  171. $store = $this->psl['store'];
  172. /* Encrypt session. */
  173. try {
  174. $crypto->_algo = $this->cryptAlgo;
  175. $crypto->_mode = $this->cryptMode;
  176. $encrypted = $crypto->encrypt($data, $this->secret);
  177. /* Destroy old session. */
  178. if($this->newID != $this->currID) {
  179. $this->destroy($this->currID);
  180. }
  181. /* Write new session, with new ID. */
  182. return $store->write('session', $this->newID, $encrypted);
  183. } catch (\phpSec\Exception $e) {
  184. return false;
  185. }
  186. }
  187. /**
  188. * Set the cookie with the secret.
  189. *
  190. * @return true
  191. */
  192. public function setSecret() {
  193. $rand = $this->psl['crypt/rand'];
  194. $this->secret = $rand->bytes(32);
  195. $cookieParam = session_get_cookie_params();
  196. setcookie(
  197. $this->keyCookie,
  198. base64_encode($this->secret),
  199. $cookieParam['lifetime'],
  200. $cookieParam['path'],
  201. $cookieParam['domain'],
  202. $cookieParam['secure'],
  203. $cookieParam['httponly']
  204. );
  205. return true;
  206. }
  207. }