Rev 1086 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1086 | Rev 1116 | ||
---|---|---|---|
Line 26... | Line 26... | ||
26 | class OIDplusSessionHandler extends OIDplusBaseClass implements OIDplusGetterSetterInterface { |
26 | class OIDplusSessionHandler extends OIDplusBaseClass implements OIDplusGetterSetterInterface { |
27 | 27 | ||
28 | private $secret = ''; |
28 | private $secret = ''; |
29 | protected $sessionLifetime = 0; |
29 | protected $sessionLifetime = 0; |
30 | 30 | ||
- | 31 | /** |
|
- | 32 | * @throws OIDplusException |
|
- | 33 | */ |
|
31 | public function __construct() { |
34 | public function __construct() { |
32 | $this->sessionLifetime = OIDplus::baseConfig()->getValue('SESSION_LIFETIME', 30*60); |
35 | $this->sessionLifetime = OIDplus::baseConfig()->getValue('SESSION_LIFETIME', 30*60); |
33 | $this->secret = OIDplus::baseConfig()->getValue('SERVER_SECRET'); |
36 | $this->secret = OIDplus::baseConfig()->getValue('SERVER_SECRET'); |
34 | 37 | ||
35 | // **PREVENTING SESSION HIJACKING** |
38 | // **PREVENTING SESSION HIJACKING** |
Line 54... | Line 57... | ||
54 | @ini_set('session.use_strict_mode', '1'); |
57 | @ini_set('session.use_strict_mode', '1'); |
55 | 58 | ||
56 | @ini_set('session.gc_maxlifetime', $this->sessionLifetime); |
59 | @ini_set('session.gc_maxlifetime', $this->sessionLifetime); |
57 | } |
60 | } |
58 | 61 | ||
- | 62 | /** |
|
- | 63 | * @return void |
|
- | 64 | * @throws OIDplusException |
|
- | 65 | */ |
|
59 | protected function sessionSafeStart() { |
66 | protected function sessionSafeStart() { |
60 | if (!isset($_SESSION)) { |
67 | if (!isset($_SESSION)) { |
61 | // TODO: session_name() makes some problems. Leave it away for now. |
68 | // TODO: session_name() makes some problems. Leave it away for now. |
62 | //session_name('OIDplus_SESHDLR'); |
69 | //session_name('OIDplus_SESHDLR'); |
63 | if (!session_start()) { |
70 | if (!session_start()) { |
Line 81... | Line 88... | ||
81 | OIDplus::cookieUtils()->unsetcookie(session_name()); // remove cookie, so GDPR people are happy |
88 | OIDplus::cookieUtils()->unsetcookie(session_name()); // remove cookie, so GDPR people are happy |
82 | } |
89 | } |
83 | } |
90 | } |
84 | } |
91 | } |
85 | 92 | ||
- | 93 | /** |
|
- | 94 | * @return void |
|
- | 95 | */ |
|
86 | function __destruct() { |
96 | function __destruct() { |
87 | session_write_close(); |
97 | session_write_close(); |
88 | } |
98 | } |
89 | 99 | ||
90 | private $cacheSetValues = array(); // Important if you do a setValue() followed by an getValue() |
100 | private $cacheSetValues = array(); // Important if you do a setValue() followed by an getValue() |
91 | 101 | ||
- | 102 | /** |
|
- | 103 | * @param string $name |
|
- | 104 | * @param mixed $value |
|
- | 105 | * @return void |
|
- | 106 | * @throws OIDplusException |
|
- | 107 | */ |
|
92 | public function setValue($name, $value) { |
108 | public function setValue(string $name, $value) { |
93 | $enc_data = self::encrypt($value, $this->secret); |
109 | $enc_data = self::encrypt($value, $this->secret); |
94 | 110 | ||
95 | $this->cacheSetValues[$name] = $enc_data; |
111 | $this->cacheSetValues[$name] = $enc_data; |
96 | 112 | ||
97 | $this->sessionSafeStart(); |
113 | $this->sessionSafeStart(); |
98 | OIDplus::cookieUtils()->setcookie(session_name(),session_id(),time()+$this->sessionLifetime); |
114 | OIDplus::cookieUtils()->setcookie(session_name(),session_id(),time()+$this->sessionLifetime); |
99 | 115 | ||
100 | $_SESSION[$name] = $enc_data; |
116 | $_SESSION[$name] = $enc_data; |
101 | } |
117 | } |
102 | 118 | ||
- | 119 | /** |
|
- | 120 | * @param string $name |
|
- | 121 | * @param mixed|null $default |
|
- | 122 | * @return mixed|null |
|
- | 123 | * @throws OIDplusException |
|
- | 124 | */ |
|
103 | public function getValue($name, $default = NULL) { |
125 | public function getValue(string $name, $default = NULL) { |
104 | if (isset($this->cacheSetValues[$name])) return self::decrypt($this->cacheSetValues[$name], $this->secret); |
126 | if (isset($this->cacheSetValues[$name])) return self::decrypt($this->cacheSetValues[$name], $this->secret); |
105 | 127 | ||
106 | if (!$this->isActive()) return $default; // GDPR: Only start a session when we really need one |
128 | if (!$this->isActive()) return $default; // GDPR: Only start a session when we really need one |
107 | $this->sessionSafeStart(); |
129 | $this->sessionSafeStart(); |
108 | OIDplus::cookieUtils()->setcookie(session_name(),session_id(),time()+$this->sessionLifetime); |
130 | OIDplus::cookieUtils()->setcookie(session_name(),session_id(),time()+$this->sessionLifetime); |
109 | 131 | ||
110 | if (!isset($_SESSION[$name])) return $default; |
132 | if (!isset($_SESSION[$name])) return $default; |
111 | return self::decrypt($_SESSION[$name], $this->secret); |
133 | return self::decrypt($_SESSION[$name], $this->secret); |
112 | } |
134 | } |
113 | 135 | ||
- | 136 | /** |
|
- | 137 | * @param string $name |
|
- | 138 | * @return bool |
|
- | 139 | * @throws OIDplusException |
|
- | 140 | */ |
|
114 | public function exists($name) { |
141 | public function exists(string $name): bool { |
115 | if (isset($this->cacheSetValues[$name])) return true; |
142 | if (isset($this->cacheSetValues[$name])) return true; |
116 | 143 | ||
117 | if (!$this->isActive()) return false; // GDPR: Only start a session when we really need one |
144 | if (!$this->isActive()) return false; // GDPR: Only start a session when we really need one |
118 | $this->sessionSafeStart(); |
145 | $this->sessionSafeStart(); |
119 | OIDplus::cookieUtils()->setcookie(session_name(),session_id(),time()+$this->sessionLifetime); |
146 | OIDplus::cookieUtils()->setcookie(session_name(),session_id(),time()+$this->sessionLifetime); |
120 | 147 | ||
121 | if (!isset($_SESSION[$name])) return false; |
148 | return isset($_SESSION[$name]); |
122 | } |
149 | } |
123 | 150 | ||
- | 151 | /** |
|
- | 152 | * @param string $name |
|
- | 153 | * @return void |
|
- | 154 | * @throws OIDplusException |
|
- | 155 | */ |
|
124 | public function delete($name) { |
156 | public function delete(string $name) { |
125 | if (isset($this->cacheSetValues[$name])) unset($this->cacheSetValues[$name]); |
157 | if (isset($this->cacheSetValues[$name])) unset($this->cacheSetValues[$name]); |
126 | 158 | ||
127 | if (!$this->isActive()) return; // GDPR: Only start a session when we really need one |
159 | if (!$this->isActive()) return; // GDPR: Only start a session when we really need one |
128 | $this->sessionSafeStart(); |
160 | $this->sessionSafeStart(); |
129 | OIDplus::cookieUtils()->setcookie(session_name(),session_id(),time()+$this->sessionLifetime); |
161 | OIDplus::cookieUtils()->setcookie(session_name(),session_id(),time()+$this->sessionLifetime); |
130 | 162 | ||
131 | unset($_SESSION[$name]); |
163 | unset($_SESSION[$name]); |
132 | } |
164 | } |
133 | 165 | ||
- | 166 | /** |
|
- | 167 | * @return void |
|
- | 168 | * @throws OIDplusException |
|
- | 169 | */ |
|
134 | public function destroySession() { |
170 | public function destroySession() { |
135 | if (!$this->isActive()) return; |
171 | if (!$this->isActive()) return; |
136 | 172 | ||
137 | $this->sessionSafeStart(); |
173 | $this->sessionSafeStart(); |
138 | OIDplus::cookieUtils()->setcookie(session_name(),session_id(),time()+$this->sessionLifetime); |
174 | OIDplus::cookieUtils()->setcookie(session_name(),session_id(),time()+$this->sessionLifetime); |
Line 141... | Line 177... | ||
141 | session_destroy(); |
177 | session_destroy(); |
142 | session_write_close(); |
178 | session_write_close(); |
143 | OIDplus::cookieUtils()->unsetcookie(session_name()); // remove cookie, so GDPR people are happy |
179 | OIDplus::cookieUtils()->unsetcookie(session_name()); // remove cookie, so GDPR people are happy |
144 | } |
180 | } |
145 | 181 | ||
- | 182 | /** |
|
- | 183 | * @return bool |
|
- | 184 | */ |
|
146 | public function isActive() { |
185 | public function isActive(): bool { |
147 | return isset($_COOKIE[session_name()]); |
186 | return isset($_COOKIE[session_name()]); |
148 | } |
187 | } |
149 | 188 | ||
- | 189 | /** |
|
- | 190 | * @param string $data |
|
- | 191 | * @param string $key |
|
- | 192 | * @return string |
|
- | 193 | * @throws \Exception |
|
- | 194 | */ |
|
150 | protected static function encrypt($data, $key) { |
195 | protected static function encrypt(string $data, string $key): string { |
151 | if (function_exists('openssl_encrypt')) { |
196 | if (function_exists('openssl_encrypt')) { |
152 | $iv = random_bytes(16); // AES block size in CBC mode |
197 | $iv = random_bytes(16); // AES block size in CBC mode |
153 | // Encryption |
198 | // Encryption |
154 | $ciphertext = openssl_encrypt( |
199 | $ciphertext = openssl_encrypt( |
155 | $data, |
200 | $data, |
Line 166... | Line 211... | ||
166 | $hmac = sha3_512_hmac($data, $key, true); |
211 | $hmac = sha3_512_hmac($data, $key, true); |
167 | return $hmac . $data; |
212 | return $hmac . $data; |
168 | } |
213 | } |
169 | } |
214 | } |
170 | 215 | ||
- | 216 | /** |
|
- | 217 | * @param string $data |
|
- | 218 | * @param string $key |
|
- | 219 | * @return string |
|
- | 220 | * @throws OIDplusException |
|
- | 221 | */ |
|
171 | protected static function decrypt($data, $key) { |
222 | protected static function decrypt(string $data, string $key): string { |
172 | if (function_exists('openssl_decrypt')) { |
223 | if (function_exists('openssl_decrypt')) { |
173 | $hmac = mb_substr($data, 0, 64, '8bit'); |
224 | $hmac = mb_substr($data, 0, 64, '8bit'); |
174 | $iv = mb_substr($data, 64, 16, '8bit'); |
225 | $iv = mb_substr($data, 64, 16, '8bit'); |
175 | $ciphertext = mb_substr($data, 80, null, '8bit'); |
226 | $ciphertext = mb_substr($data, 80, null, '8bit'); |
176 | // Authentication |
227 | // Authentication |