summaryrefslogtreecommitdiff
path: root/session.c
diff options
context:
space:
mode:
authorStefan Esser2010-02-21 11:44:54 +0100
committerStefan Esser2010-02-21 11:44:54 +0100
commit36dbfacbe64697d959f524e537b15b73c090d898 (patch)
treef1c7ce1409b0e7765fc72d550546967fcf0f9717 /session.c
Inital commit
Diffstat (limited to 'session.c')
-rw-r--r--session.c714
1 files changed, 714 insertions, 0 deletions
diff --git a/session.c b/session.c
new file mode 100644
index 0000000..b784d9b
--- /dev/null
+++ b/session.c
@@ -0,0 +1,714 @@
1/*
2 +----------------------------------------------------------------------+
3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007 SektionEins GmbH |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
16 | Author: Stefan Esser <sesser@sektioneins.de> |
17 +----------------------------------------------------------------------+
18*/
19/*
20 $Id: session.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $
21*/
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "php.h"
28#include "TSRM.h"
29#include "SAPI.h"
30#include "php_ini.h"
31#include "php_suhosin.h"
32#include "ext/standard/base64.h"
33#include "sha256.h"
34
35#define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
36#define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
37#define PS_READ_ARGS void **mod_data, const char *key, char **val, int *vallen TSRMLS_DC
38#define PS_WRITE_ARGS void **mod_data, const char *key, const char *val, const int vallen TSRMLS_DC
39#define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
40#define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
41#define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
42
43typedef struct ps_module_struct {
44 const char *s_name;
45 int (*s_open)(PS_OPEN_ARGS);
46 int (*s_close)(PS_CLOSE_ARGS);
47 int (*s_read)(PS_READ_ARGS);
48 int (*s_write)(PS_WRITE_ARGS);
49 int (*s_destroy)(PS_DESTROY_ARGS);
50 int (*s_gc)(PS_GC_ARGS);
51 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
52} ps_module;
53
54typedef enum {
55 php_session_disabled,
56 php_session_none,
57 php_session_active
58} php_session_status;
59
60#define PS_SERIALIZER_ENCODE_ARGS char **newstr, int *newlen TSRMLS_DC
61#define PS_SERIALIZER_DECODE_ARGS const char *val, int vallen TSRMLS_DC
62
63typedef struct ps_serializer_struct {
64 const char *name;
65 int (*encode)(PS_SERIALIZER_ENCODE_ARGS);
66 int (*decode)(PS_SERIALIZER_DECODE_ARGS);
67} ps_serializer;
68
69typedef struct _php_ps_globals_43_44 {
70 char *save_path;
71 char *session_name;
72 char *id;
73 char *extern_referer_chk;
74 char *entropy_file;
75 char *cache_limiter;
76 long entropy_length;
77 long cookie_lifetime;
78 char *cookie_path;
79 char *cookie_domain;
80 zend_bool cookie_secure;
81 ps_module *mod;
82 void *mod_data;
83 php_session_status session_status;
84 long gc_probability;
85 long gc_divisor;
86 long gc_maxlifetime;
87 int module_number;
88 long cache_expire;
89 zend_bool bug_compat; /* Whether to behave like PHP 4.2 and earlier */
90 zend_bool bug_compat_warn; /* Whether to warn about it */
91 const struct ps_serializer_struct *serializer;
92 zval *http_session_vars;
93 zend_bool auto_start;
94 zend_bool use_cookies;
95 zend_bool use_only_cookies;
96 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
97 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
98 int send_cookie;
99 int define_sid;
100} php_ps_globals_43_44;
101
102typedef struct _php_ps_globals_50_51 {
103 char *save_path;
104 char *session_name;
105 char *id;
106 char *extern_referer_chk;
107 char *entropy_file;
108 char *cache_limiter;
109 long entropy_length;
110 long cookie_lifetime;
111 char *cookie_path;
112 char *cookie_domain;
113 zend_bool cookie_secure;
114 ps_module *mod;
115 void *mod_data;
116 php_session_status session_status;
117 long gc_probability;
118 long gc_divisor;
119 long gc_maxlifetime;
120 int module_number;
121 long cache_expire;
122 zend_bool bug_compat; /* Whether to behave like PHP 4.2 and earlier */
123 zend_bool bug_compat_warn; /* Whether to warn about it */
124 const struct ps_serializer_struct *serializer;
125 zval *http_session_vars;
126 zend_bool auto_start;
127 zend_bool use_cookies;
128 zend_bool use_only_cookies;
129 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
130 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
131
132 long hash_func;
133 long hash_bits_per_character;
134 int send_cookie;
135 int define_sid;
136} php_ps_globals_50_51;
137
138typedef struct _php_ps_globals_52_60 {
139 char *save_path;
140 char *session_name;
141 char *id;
142 char *extern_referer_chk;
143 char *entropy_file;
144 char *cache_limiter;
145 long entropy_length;
146 long cookie_lifetime;
147 char *cookie_path;
148 char *cookie_domain;
149 zend_bool cookie_secure;
150 zend_bool cookie_httponly;
151 ps_module *mod;
152 void *mod_data;
153 php_session_status session_status;
154 long gc_probability;
155 long gc_divisor;
156 long gc_maxlifetime;
157 int module_number;
158 long cache_expire;
159 zend_bool bug_compat; /* Whether to behave like PHP 4.2 and earlier */
160 zend_bool bug_compat_warn; /* Whether to warn about it */
161 const struct ps_serializer_struct *serializer;
162 zval *http_session_vars;
163 zend_bool auto_start;
164 zend_bool use_cookies;
165 zend_bool use_only_cookies;
166 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
167 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
168
169 long hash_func;
170 long hash_bits_per_character;
171 int send_cookie;
172 int define_sid;
173 zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */
174} php_ps_globals_52_60;
175
176
177#ifdef ZTS
178static ts_rsrc_id session_globals_id = 0;
179# if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 2)
180# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_52_60 *, v)
181# elif (PHP_MAJOR_VERSION == 5)
182# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_50_51 *, v)
183# elif (PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION >= 3)
184# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_43_44 *, v)
185# else
186 UNSUPPORTED PHP VERSION
187# endif
188#else
189# if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 2)
190static php_ps_globals_52_60 *session_globals = NULL;
191# elif (PHP_MAJOR_VERSION == 5)
192static php_ps_globals_50_51 *session_globals = NULL;
193# elif (PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION >= 3)
194static php_ps_globals_43_44 *session_globals = NULL;
195# else
196 UNSUPPORTED PHP VERSION
197# endif
198#define SESSION_G(v) (session_globals->v)
199#endif
200
201void suhosin_get_ipv4(char *buf TSRMLS_DC)
202{
203 char *raddr = sapi_getenv("REMOTE_ADDR", sizeof("REMOTE_ADDR")-1 TSRMLS_CC);
204 int i;
205
206
207 if (raddr == NULL) {
208 memset(buf, 0, 4);
209 return;
210 }
211
212 for (i=0; i<4; i++) {
213 if (raddr[0] == 0) {
214 buf[i] = 0;
215 } else {
216 buf[i] = strtol(raddr, &raddr, 10);
217 if (raddr[0] == '.') {
218 raddr++;
219 }
220 }
221 }
222}
223
224char *suhosin_encrypt_string(char *str, int len, char *var, int vlen, char *key TSRMLS_DC)
225{
226 int padded_len, i, slen;
227 unsigned char *crypted, *tmp;
228 unsigned int check = 0x13579BDF;
229
230 if (str == NULL) {
231 return NULL;
232 }
233 if (len == 0) {
234 return estrndup("", 0);
235 }
236
237
238 suhosin_aes_gkey(4,8,key TSRMLS_CC);
239
240 padded_len = ((len+15) & ~0xF);
241 crypted = emalloc(16+padded_len+1);
242 memset(crypted, 0xff, 16+padded_len+1);
243 memcpy(crypted+16, str, len+1);
244
245 /* calculate check value */
246 for (i = 0; i<vlen; i++) {
247 check = (check << 3) | (check >> (32-3));
248 check += check << 1;
249 check ^= (unsigned char)var[i];
250 }
251 for (i = 0; i<len; i++) {
252 check = (check << 3) | (check >> (32-3));
253 check += check << 1;
254 check ^= (unsigned char)str[i];
255 }
256
257 /* store ip value */
258 suhosin_get_ipv4(crypted+4 TSRMLS_CC);
259
260 /* store check value */
261 crypted[8] = check & 0xff;
262 crypted[9] = (check >> 8) & 0xff;
263 crypted[10] = (check >> 16) & 0xff;
264 crypted[11] = (check >> 24) & 0xff;
265
266 /* store original length */
267 crypted[12] = len & 0xff;
268 crypted[13] = (len >> 8) & 0xff;
269 crypted[14] = (len >> 16) & 0xff;
270 crypted[15] = (len >> 24) & 0xff;
271
272 for (i=0, tmp=crypted; i<padded_len+16; i+=16, tmp+=16) {
273 if (i > 0) {
274 int j;
275 for (j=0; j<16; j++) tmp[j] ^= tmp[j-16];
276 }
277 suhosin_aes_encrypt((char *)tmp TSRMLS_CC);
278 }
279
280 tmp = php_base64_encode(crypted, padded_len+16, NULL);
281 efree(crypted);
282 slen=strlen((char *)tmp);
283 for (i=0; i<slen; i++) {
284 switch (tmp[i]) {
285 case '/': tmp[i]='-'; break;
286 case '=': tmp[i]='.'; break;
287 case '+': tmp[i]='_'; break;
288 }
289 }
290 return (char *)tmp;
291}
292
293char *suhosin_decrypt_string(char *str, int padded_len, char *var, int vlen, char *key, int *orig_len, int check_ra TSRMLS_DC)
294{
295 int len, i, o_len, invalid = 0;
296 unsigned char *decrypted, *tmp;
297 unsigned int check = 0x13579BDF;
298 char buf[4];
299
300 if (str == NULL) {
301 return NULL;
302 }
303
304 if (padded_len == 0) {
305 if (orig_len) {
306 *orig_len = 0;
307 }
308 return estrndup("", 0);
309 }
310 suhosin_aes_gkey(4,8,key TSRMLS_CC);
311
312 for (i=0; i<padded_len; i++) {
313 switch (str[i]) {
314 case '-': str[i]='/'; break;
315 case '.': str[i]='='; break;
316 case '_': str[i]='+'; break;
317 }
318 }
319
320 decrypted = php_base64_decode((unsigned char *)str, padded_len, &len);
321 if (decrypted == NULL || len < 2*16 || (len % 16) != 0) {
322error_out:
323 if (decrypted != NULL) {
324 efree(decrypted);
325 }
326 if (orig_len) {
327 *orig_len = 0;
328 }
329 return NULL;
330 }
331
332 for (i=len-16, tmp=decrypted+i; i>=0; i-=16, tmp-=16) {
333 suhosin_aes_decrypt((char *)tmp TSRMLS_CC);
334 if (i > 0) {
335 int j;
336 for (j=0; j<16; j++) tmp[j] ^= tmp[j-16];
337 }
338 }
339
340 /* retrieve orig_len */
341 o_len = decrypted[15];
342 o_len <<= 8;
343 o_len |= decrypted[14];
344 o_len <<= 8;
345 o_len |= decrypted[13];
346 o_len <<= 8;
347 o_len |= decrypted[12];
348
349 if (o_len < 0 || o_len > len-16) {
350 goto error_out;
351 }
352
353 /* calculate check value */
354 for (i = 0; i<vlen; i++) {
355 check = (check << 3) | (check >> (32-3));
356 check += check << 1;
357 check ^= (unsigned char)var[i];
358 }
359 for (i = 0; i<o_len; i++) {
360 check = (check << 3) | (check >> (32-3));
361 check += check << 1;
362 check ^= decrypted[16+i];
363 }
364
365 /* check value */
366 invalid = (decrypted[8] != (check & 0xff)) ||
367 (decrypted[9] != ((check >> 8) & 0xff)) ||
368 (decrypted[10] != ((check >> 16) & 0xff)) ||
369 (decrypted[11] != ((check >> 24) & 0xff));
370
371 /* check IP */
372 if (check_ra > 0) {
373 if (check_ra > 4) {
374 check_ra = 4;
375 }
376 suhosin_get_ipv4(&buf TSRMLS_CC);
377 if (memcmp(buf, decrypted+4, check_ra) != 0) {
378 goto error_out;
379 }
380 }
381
382 if (invalid) {
383 goto error_out;
384 }
385
386 if (orig_len) {
387 *orig_len = o_len;
388 }
389
390 memmove(decrypted, decrypted+16, o_len);
391 decrypted[o_len] = 0;
392 /* we do not realloc() here because 16 byte less
393 is simply not worth the overhead */
394 return (char *)decrypted;
395}
396
397char *suhosin_generate_key(char *key, zend_bool ua, zend_bool dr, long raddr, char *cryptkey TSRMLS_DC)
398{
399 char *_ua = NULL;
400 char *_dr = NULL;
401 char *_ra = NULL;
402 suhosin_SHA256_CTX ctx;
403
404 if (ua) {
405 _ua = sapi_getenv("HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")-1 TSRMLS_CC);
406 }
407
408 if (dr) {
409 _dr = sapi_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")-1 TSRMLS_CC);
410 }
411
412 if (raddr > 0) {
413 _ra = sapi_getenv("REMOTE_ADDR", sizeof("REMOTE_ADDR")-1 TSRMLS_CC);
414 }
415
416 SDEBUG("(suhosin_generate_key) KEY: %s - UA: %s - DR: %s - RA: %s", key,_ua,_dr,_ra);
417
418 suhosin_SHA256Init(&ctx);
419 if (key == NULL) {
420 suhosin_SHA256Update(&ctx, (unsigned char*)"D3F4UL7", sizeof("D3F4UL7"));
421 } else {
422 suhosin_SHA256Update(&ctx, (unsigned char*)key, strlen(key));
423 }
424 if (_ua) {
425 suhosin_SHA256Update(&ctx, (unsigned char*)_ua, strlen(_ua));
426 }
427 if (_dr) {
428 suhosin_SHA256Update(&ctx, (unsigned char*)_dr, strlen(_dr));
429 }
430 if (_ra) {
431 if (raddr >= 4) {
432 suhosin_SHA256Update(&ctx, (unsigned char*)_ra, strlen(_ra));
433 } else {
434 long dots = 0;
435 char *tmp = _ra;
436
437 while (*tmp) {
438 if (*tmp == '.') {
439 dots++;
440 if (dots == raddr) {
441 break;
442 }
443 }
444 tmp++;
445 }
446 suhosin_SHA256Update(&ctx, (unsigned char*)_ra, tmp-_ra);
447 }
448 }
449 suhosin_SHA256Final((unsigned char *)cryptkey, &ctx);
450 cryptkey[32] = 0; /* uhmm... not really a string */
451
452 return cryptkey;
453}
454
455
456static int (*old_OnUpdateSaveHandler)(zend_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage TSRMLS_DC) = NULL;
457static int (*old_SessionRINIT)(INIT_FUNC_ARGS) = NULL;
458
459static int suhosin_hook_s_read(void **mod_data, const char *key, char **val, int *vallen TSRMLS_DC)
460{
461 int r;
462
463 int i;char *v,*KEY=(char *)key;
464
465 /* protect session vars */
466/* if (SESSION_G(http_session_vars) && SESSION_G(http_session_vars)->type == IS_ARRAY) {
467 SESSION_G(http_session_vars)->refcount++;
468 }*/
469
470 /* protect dumb session handlers */
471 if (key == NULL || !key[0] || *mod_data == NULL) {
472regenerate:
473 SDEBUG("regenerating key is %s", key);
474 KEY = SESSION_G(id) = SESSION_G(mod)->s_create_sid(&SESSION_G(mod_data), NULL TSRMLS_CC);
475 SESSION_G(send_cookie) = 1;
476 } else if (strlen(key) > SUHOSIN_G(session_max_id_length)) {
477 suhosin_log(S_SESSION, "session id ('%s') exceeds maximum length - regenerating", KEY);
478 if (!SUHOSIN_G(simulation)) {
479 goto regenerate;
480 }
481 }
482#if (PHP_MAJOR_VERSION < 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 2)
483 else if (strpbrk(KEY, "\r\n\t <>'\"\\")) {
484 suhosin_log(S_SESSION, "session id ('%s') contains invalid chars - regenerating", KEY);
485 if (!SUHOSIN_G(simulation)) {
486 goto regenerate;
487 }
488 }
489#endif
490
491 r = SUHOSIN_G(old_s_read)(mod_data, KEY, val, vallen TSRMLS_CC);
492
493 if (r == SUCCESS && SUHOSIN_G(session_encrypt) && *vallen > 0) {
494 char cryptkey[33];
495
496 SUHOSIN_G(do_not_scan) = 1;
497 suhosin_generate_key(SUHOSIN_G(session_cryptkey), SUHOSIN_G(session_cryptua), SUHOSIN_G(session_cryptdocroot), SUHOSIN_G(session_cryptraddr), (char *)&cryptkey TSRMLS_CC);
498
499 v = *val;
500 i = *vallen;
501 *val = suhosin_decrypt_string(v, i, "", 0, (char *)&cryptkey, vallen, SUHOSIN_G(session_checkraddr) TSRMLS_CC);
502 SUHOSIN_G(do_not_scan) = 0;
503 if (*val == NULL) {
504 *val = estrndup("", 0);
505 *vallen = 0;
506 }
507 efree(v);
508 }
509
510 return r;
511}
512
513static int suhosin_hook_s_write(void **mod_data, const char *key, const char *val, const int vallen TSRMLS_DC)
514{
515 int r;
516/* int nullify = 0;*/
517 char *v = (char *)val;
518
519 /* protect dumb session handlers */
520 if (key == NULL || !key[0] || val == NULL || strlen(key) > SUHOSIN_G(session_max_id_length) || *mod_data == NULL) {
521 r = FAILURE;
522 goto return_write;
523 }
524
525 r = vallen;
526
527 if (r > 0 && SUHOSIN_G(session_encrypt)) {
528 char cryptkey[33];
529
530 SUHOSIN_G(do_not_scan) = 1;
531
532 suhosin_generate_key(SUHOSIN_G(session_cryptkey), SUHOSIN_G(session_cryptua), SUHOSIN_G(session_cryptdocroot), SUHOSIN_G(session_cryptraddr), (char *)&cryptkey TSRMLS_CC);
533
534 v = suhosin_encrypt_string(v, vallen, "", 0, (char *)&cryptkey TSRMLS_CC);
535
536 SUHOSIN_G(do_not_scan) = 0;
537 r = strlen(v);
538 }
539
540 r = SUHOSIN_G(old_s_write)(mod_data, key, v, r TSRMLS_CC);
541
542return_write:
543 /* protect session vars */
544/* if (SESSION_G(http_session_vars) && SESSION_G(http_session_vars)->type == IS_ARRAY) {
545 if (SESSION_G(http_session_vars)->refcount==1) {
546 nullify = 1;
547 }
548 zval_ptr_dtor(&SESSION_G(http_session_vars));
549 if (nullify) {
550 suhosin_log(S_SESSION, "possible session variables double free attack stopped");
551 SESSION_G(http_session_vars) = NULL;
552 }
553 }*/
554
555 return r;
556}
557
558static int suhosin_hook_s_destroy(void **mod_data, const char *key TSRMLS_DC)
559{
560 int r;
561
562 /* protect dumb session handlers */
563 if (key == NULL || !key[0] || strlen(key) > SUHOSIN_G(session_max_id_length) || *mod_data == NULL) {
564 return FAILURE;
565 }
566
567 r = SUHOSIN_G(old_s_destroy)(mod_data, key TSRMLS_CC);
568
569 return r;
570}
571
572static void suhosin_hook_session_module(TSRMLS_D)
573{
574 ps_module *old_mod = SESSION_G(mod), *mod;
575
576 if (old_mod == NULL || SUHOSIN_G(s_module) == old_mod) {
577 return;
578 }
579 if (SUHOSIN_G(s_module) == NULL) {
580 SUHOSIN_G(s_module) = mod = malloc(sizeof(ps_module));
581 if (mod == NULL) {
582 return;
583 }
584 }
585 mod = SUHOSIN_G(s_module);
586 memcpy(mod, old_mod, sizeof(ps_module));
587
588 SUHOSIN_G(old_s_read) = mod->s_read;
589 mod->s_read = suhosin_hook_s_read;
590 SUHOSIN_G(old_s_write) = mod->s_write;
591 mod->s_write = suhosin_hook_s_write;
592 SUHOSIN_G(old_s_destroy) = mod->s_destroy;
593 mod->s_destroy = suhosin_hook_s_destroy;
594
595 SESSION_G(mod) = mod;
596}
597
598static PHP_INI_MH(suhosin_OnUpdateSaveHandler)
599{
600 int r;
601
602 r = old_OnUpdateSaveHandler(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
603
604 suhosin_hook_session_module(TSRMLS_C);
605
606 return r;
607}
608
609
610static int suhosin_hook_session_RINIT(INIT_FUNC_ARGS)
611{
612 if (SESSION_G(mod) == NULL) {
613 char *value = zend_ini_string("session.save_handler", sizeof("session.save_handler"), 0);
614
615 if (value) {
616 suhosin_OnUpdateSaveHandler(NULL, value, strlen(value), NULL, NULL, NULL, 0 TSRMLS_CC);
617 }
618 }
619 return old_SessionRINIT(INIT_FUNC_ARGS_PASSTHRU);
620}
621
622void suhosin_hook_session(TSRMLS_D)
623{
624 zend_ini_entry *ini_entry;
625 zend_module_entry *module;
626#ifdef ZTS
627 ts_rsrc_id *ps_globals_id_ptr;
628#endif
629
630 if (zend_hash_find(&module_registry, "session", sizeof("session"), (void**)&module) == FAILURE) {
631 return;
632 }
633 /* retrieve globals from module entry struct if possible */
634#if PHP_VERSION_ID >= 50200
635#ifdef ZTS
636 if (session_globals_id == 0) {
637 session_globals_id = *module->globals_id_ptr;
638 }
639#else
640 if (session_globals == NULL) {
641 session_globals = module->globals_ptr;
642 }
643#endif
644#else
645 /* retrieve globals from symbols if PHP version is old */
646#ifdef ZTS
647 if (session_globals_id == 0) {
648 ps_globals_id_ptr = DL_FETCH_SYMBOL(module->handle, "ps_globals_id");
649 if (ps_globals_id_ptr == NULL) {
650 ps_globals_id_ptr = DL_FETCH_SYMBOL(module->handle, "_ps_globals_id");
651 }
652 if (ps_globals_id_ptr == NULL) {
653 return;
654 }
655
656 session_globals_id = *ps_globals_id_ptr;
657 }
658#else
659 if (session_globals == NULL) {
660 session_globals = DL_FETCH_SYMBOL(module->handle, "ps_globals");
661 if (session_globals == NULL) {
662 session_globals = DL_FETCH_SYMBOL(module->handle, "_ps_globals");
663 }
664 if (session_globals == NULL) {
665 return;
666 }
667 }
668#endif
669#endif
670 if (old_OnUpdateSaveHandler != NULL) {
671 return;
672 }
673
674 /* hook request startup function of session module */
675 old_SessionRINIT = module->request_startup_func;
676 module->request_startup_func = suhosin_hook_session_RINIT;
677
678 /* retrieve pointer to session.save_handler ini entry */
679 if (zend_hash_find(EG(ini_directives), "session.save_handler", sizeof("session.save_handler"), (void **) &ini_entry) == FAILURE) {
680 return;
681 }
682 SUHOSIN_G(s_module) = NULL;
683
684 /* replace OnUpdateMemoryLimit handler */
685 old_OnUpdateSaveHandler = ini_entry->on_modify;
686 ini_entry->on_modify = suhosin_OnUpdateSaveHandler;
687
688 suhosin_hook_session_module(TSRMLS_C);
689}
690
691void suhosin_unhook_session(TSRMLS_D)
692{
693 if (old_OnUpdateSaveHandler != NULL) {
694 zend_ini_entry *ini_entry;
695
696 /* retrieve pointer to session.save_handler ini entry */
697 if (zend_hash_find(EG(ini_directives), "session.save_handler", sizeof("session.save_handler"), (void **) &ini_entry) == FAILURE) {
698 return;
699 }
700 ini_entry->on_modify = old_OnUpdateSaveHandler;
701
702 old_OnUpdateSaveHandler = NULL;
703 }
704
705}
706
707/*
708 * Local variables:
709 * tab-width: 4
710 * c-basic-offset: 4
711 * End:
712 * vim600: sw=4 ts=4 fdm=marker
713 * vim<600: sw=4 ts=4
714 */