summaryrefslogtreecommitdiff
path: root/session.c
diff options
context:
space:
mode:
authorBen Fuhrmannek2014-11-12 18:06:42 +0100
committerBen Fuhrmannek2014-11-12 18:06:42 +0100
commitd35835eabeda75dffe58b6bad50790e6adfbd156 (patch)
tree632a6c3337eec7293acd1b1104edd9fe30d790f4 /session.c
parent17849bcb55f757e6271c7d3e21ab34ccec849e07 (diff)
removed session structs + split crypt funcs
Diffstat (limited to 'session.c')
-rw-r--r--session.c760
1 files changed, 30 insertions, 730 deletions
diff --git a/session.c b/session.c
index 827c6b7..548786f 100644
--- a/session.c
+++ b/session.c
@@ -1,19 +1,20 @@
1/* 1/*
2 +----------------------------------------------------------------------+ 2 +----------------------------------------------------------------------+
3 | Suhosin Version 1 | 3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+ 4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project | 5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007-2014 SektionEins GmbH | 6 | Copyright (c) 2007-2014 SektionEins GmbH |
7 +----------------------------------------------------------------------+ 7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, | 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 | 9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: | 10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt | 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 | 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 | 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. | 14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+ 15 +----------------------------------------------------------------------+
16 | Author: Stefan Esser <sesser@sektioneins.de> | 16 | Authors: Stefan Esser <sesser@sektioneins.de> |
17 | Ben Fuhrmannek <ben.fuhrmannek@sektioneins.de> |
17 +----------------------------------------------------------------------+ 18 +----------------------------------------------------------------------+
18*/ 19*/
19/* 20/*
@@ -29,10 +30,8 @@
29#include "SAPI.h" 30#include "SAPI.h"
30#include "php_ini.h" 31#include "php_ini.h"
31#include "php_suhosin.h" 32#include "php_suhosin.h"
32#include "ext/standard/base64.h"
33#include "ext/standard/php_smart_str.h" 33#include "ext/standard/php_smart_str.h"
34#include "ext/standard/php_var.h" 34#include "ext/standard/php_var.h"
35#include "sha256.h"
36 35
37#include <fcntl.h> 36#include <fcntl.h>
38 37
@@ -40,480 +39,19 @@
40# include "ext/hash/php_hash.h" 39# include "ext/hash/php_hash.h"
41#endif 40#endif
42 41
43#define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC 42#ifdef HAVE_PHP_SESSION
44#define PS_CLOSE_ARGS void **mod_data TSRMLS_DC 43#include "ext/session/php_session.h"
45#define PS_READ_ARGS void **mod_data, const char *key, char **val, int *vallen TSRMLS_DC
46#define PS_WRITE_ARGS void **mod_data, const char *key, const char *val, const int vallen TSRMLS_DC
47#define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
48#define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
49#define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
50
51typedef struct ps_module_struct {
52 const char *s_name;
53 int (*s_open)(PS_OPEN_ARGS);
54 int (*s_close)(PS_CLOSE_ARGS);
55 int (*s_read)(PS_READ_ARGS);
56 int (*s_write)(PS_WRITE_ARGS);
57 int (*s_destroy)(PS_DESTROY_ARGS);
58 int (*s_gc)(PS_GC_ARGS);
59 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
60} ps_module;
61
62typedef enum {
63 php_session_disabled,
64 php_session_none,
65 php_session_active
66} php_session_status;
67
68#define PS_SERIALIZER_ENCODE_ARGS char **newstr, int *newlen TSRMLS_DC
69#define PS_SERIALIZER_DECODE_ARGS const char *val, int vallen TSRMLS_DC
70
71typedef struct ps_serializer_struct {
72 const char *name;
73 int (*encode)(PS_SERIALIZER_ENCODE_ARGS);
74 int (*decode)(PS_SERIALIZER_DECODE_ARGS);
75} ps_serializer;
76
77typedef struct _php_ps_globals_43_44 {
78 char *save_path;
79 char *session_name;
80 char *id;
81 char *extern_referer_chk;
82 char *entropy_file;
83 char *cache_limiter;
84 long entropy_length;
85 long cookie_lifetime;
86 char *cookie_path;
87 char *cookie_domain;
88 zend_bool cookie_secure;
89 ps_module *mod;
90 void *mod_data;
91 php_session_status session_status;
92 long gc_probability;
93 long gc_divisor;
94 long gc_maxlifetime;
95 int module_number;
96 long cache_expire;
97 zend_bool bug_compat; /* Whether to behave like PHP 4.2 and earlier */
98 zend_bool bug_compat_warn; /* Whether to warn about it */
99 const struct ps_serializer_struct *serializer;
100 zval *http_session_vars;
101 zend_bool auto_start;
102 zend_bool use_cookies;
103 zend_bool use_only_cookies;
104 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
105 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
106 int send_cookie;
107 int define_sid;
108} php_ps_globals_43_44;
109
110typedef struct _php_ps_globals_50_51 {
111 char *save_path;
112 char *session_name;
113 char *id;
114 char *extern_referer_chk;
115 char *entropy_file;
116 char *cache_limiter;
117 long entropy_length;
118 long cookie_lifetime;
119 char *cookie_path;
120 char *cookie_domain;
121 zend_bool cookie_secure;
122 ps_module *mod;
123 void *mod_data;
124 php_session_status session_status;
125 long gc_probability;
126 long gc_divisor;
127 long gc_maxlifetime;
128 int module_number;
129 long cache_expire;
130 zend_bool bug_compat; /* Whether to behave like PHP 4.2 and earlier */
131 zend_bool bug_compat_warn; /* Whether to warn about it */
132 const struct ps_serializer_struct *serializer;
133 zval *http_session_vars;
134 zend_bool auto_start;
135 zend_bool use_cookies;
136 zend_bool use_only_cookies;
137 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
138 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
139
140 long hash_func;
141 long hash_bits_per_character;
142 int send_cookie;
143 int define_sid;
144} php_ps_globals_50_51;
145
146typedef struct _php_ps_globals_52 {
147 char *save_path;
148 char *session_name;
149 char *id;
150 char *extern_referer_chk;
151 char *entropy_file;
152 char *cache_limiter;
153 long entropy_length;
154 long cookie_lifetime;
155 char *cookie_path;
156 char *cookie_domain;
157 zend_bool cookie_secure;
158 zend_bool cookie_httponly;
159 ps_module *mod;
160 void *mod_data;
161 php_session_status session_status;
162 long gc_probability;
163 long gc_divisor;
164 long gc_maxlifetime;
165 int module_number;
166 long cache_expire;
167 zend_bool bug_compat; /* Whether to behave like PHP 4.2 and earlier */
168 zend_bool bug_compat_warn; /* Whether to warn about it */
169 const struct ps_serializer_struct *serializer;
170 zval *http_session_vars;
171 zend_bool auto_start;
172 zend_bool use_cookies;
173 zend_bool use_only_cookies;
174 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
175 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
176
177 long hash_func;
178 long hash_bits_per_character;
179 int send_cookie;
180 int define_sid;
181 zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */
182} php_ps_globals_52;
183
184typedef struct _php_ps_globals_53 {
185 char *save_path;
186 char *session_name;
187 char *id;
188 char *extern_referer_chk;
189 char *entropy_file;
190 char *cache_limiter;
191 long entropy_length;
192 long cookie_lifetime;
193 char *cookie_path;
194 char *cookie_domain;
195 zend_bool cookie_secure;
196 zend_bool cookie_httponly;
197 ps_module *mod;
198 void *mod_data;
199 php_session_status session_status;
200 long gc_probability;
201 long gc_divisor;
202 long gc_maxlifetime;
203 int module_number;
204 long cache_expire;
205 union {
206 zval *names[6];
207 struct {
208 zval *ps_open;
209 zval *ps_close;
210 zval *ps_read;
211 zval *ps_write;
212 zval *ps_destroy;
213 zval *ps_gc;
214 } name;
215 } mod_user_names;
216 zend_bool bug_compat; /* Whether to behave like PHP 4.2 and earlier */
217 zend_bool bug_compat_warn; /* Whether to warn about it */
218 const struct ps_serializer_struct *serializer;
219 zval *http_session_vars;
220 zend_bool auto_start;
221 zend_bool use_cookies;
222 zend_bool use_only_cookies;
223 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
224 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
225
226 long hash_func;
227#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
228 php_hash_ops *hash_ops;
229#endif
230 long hash_bits_per_character;
231 int send_cookie;
232 int define_sid;
233 zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */
234} php_ps_globals_53;
235
236#if PHP_VERSION_ID >= 50400
237typedef struct _php_session_rfc1867_progress_54_55_56 {
238
239 size_t sname_len;
240 zval sid;
241 smart_str key;
242
243 long update_step;
244 long next_update;
245 double next_update_time;
246 zend_bool cancel_upload;
247 zend_bool apply_trans_sid;
248 size_t content_length;
249
250 zval *data; /* the array exported to session data */
251 zval *post_bytes_processed; /* data["bytes_processed"] */
252 zval *files; /* data["files"] array */
253 zval *current_file; /* array of currently uploading file */
254 zval *current_file_bytes_processed;
255} php_session_rfc1867_progress_54_55_56;
256
257typedef struct _php_ps_globals_54 {
258 char *save_path;
259 char *session_name;
260 char *id;
261 char *extern_referer_chk;
262 char *entropy_file;
263 char *cache_limiter;
264 long entropy_length;
265 long cookie_lifetime;
266 char *cookie_path;
267 char *cookie_domain;
268 zend_bool cookie_secure;
269 zend_bool cookie_httponly;
270 ps_module *mod;
271 ps_module *default_mod;
272 void *mod_data;
273 php_session_status session_status;
274 long gc_probability;
275 long gc_divisor;
276 long gc_maxlifetime;
277 int module_number;
278 long cache_expire;
279 union {
280 zval *names[6];
281 struct {
282 zval *ps_open;
283 zval *ps_close;
284 zval *ps_read;
285 zval *ps_write;
286 zval *ps_destroy;
287 zval *ps_gc;
288 } name;
289 } mod_user_names;
290 int mod_user_implemented;
291 int mod_user_is_open;
292 const struct ps_serializer_struct *serializer;
293 zval *http_session_vars;
294 zend_bool auto_start;
295 zend_bool use_cookies;
296 zend_bool use_only_cookies;
297 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
298 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
299
300 long hash_func;
301#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
302 php_hash_ops *hash_ops;
303#endif
304 long hash_bits_per_character;
305 int send_cookie;
306 int define_sid;
307 zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */
308
309 php_session_rfc1867_progress_54_55_56 *rfc1867_progress;
310 zend_bool rfc1867_enabled; /* session.upload_progress.enabled */
311 zend_bool rfc1867_cleanup; /* session.upload_progress.cleanup */
312 smart_str rfc1867_prefix; /* session.upload_progress.prefix */
313 smart_str rfc1867_name; /* session.upload_progress.name */
314 long rfc1867_freq; /* session.upload_progress.freq */
315 double rfc1867_min_freq; /* session.upload_progress.min_freq */
316} php_ps_globals_54;
317#endif
318
319#if PHP_VERSION_ID >= 50500
320typedef struct _php_ps_globals_55 {
321 char *save_path;
322 char *session_name;
323 char *id;
324 char *extern_referer_chk;
325 char *entropy_file;
326 char *cache_limiter;
327 long entropy_length;
328 long cookie_lifetime;
329 char *cookie_path;
330 char *cookie_domain;
331 zend_bool cookie_secure;
332 zend_bool cookie_httponly;
333 ps_module *mod;
334 ps_module *default_mod;
335 void *mod_data;
336 php_session_status session_status;
337 long gc_probability;
338 long gc_divisor;
339 long gc_maxlifetime;
340 int module_number;
341 long cache_expire;
342 union {
343 zval *names[7];
344 struct {
345 zval *ps_open;
346 zval *ps_close;
347 zval *ps_read;
348 zval *ps_write;
349 zval *ps_destroy;
350 zval *ps_gc;
351 zval *ps_create_sid;
352 } name;
353 } mod_user_names;
354 int mod_user_implemented;
355 int mod_user_is_open;
356 const struct ps_serializer_struct *serializer;
357 zval *http_session_vars;
358 zend_bool auto_start;
359 zend_bool use_cookies;
360 zend_bool use_only_cookies;
361 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
362 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
363
364 long hash_func;
365#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
366 php_hash_ops *hash_ops;
367#endif
368 long hash_bits_per_character;
369 int send_cookie;
370 int define_sid;
371 zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */
372
373 php_session_rfc1867_progress_54_55_56 *rfc1867_progress;
374 zend_bool rfc1867_enabled; /* session.upload_progress.enabled */
375 zend_bool rfc1867_cleanup; /* session.upload_progress.cleanup */
376 smart_str rfc1867_prefix; /* session.upload_progress.prefix */
377 smart_str rfc1867_name; /* session.upload_progress.name */
378 long rfc1867_freq; /* session.upload_progress.freq */
379 double rfc1867_min_freq; /* session.upload_progress.min_freq */
380
381 zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
382} php_ps_globals_55;
383
384typedef struct _php_ps_globals_56 {
385 char *save_path;
386 char *session_name;
387 char *id;
388 char *extern_referer_chk;
389 char *entropy_file;
390 char *cache_limiter;
391 long entropy_length;
392 long cookie_lifetime;
393 char *cookie_path;
394 char *cookie_domain;
395 zend_bool cookie_secure;
396 zend_bool cookie_httponly;
397 ps_module *mod;
398 ps_module *default_mod;
399 void *mod_data;
400 php_session_status session_status;
401 long gc_probability;
402 long gc_divisor;
403 long gc_maxlifetime;
404 int module_number;
405 long cache_expire;
406 union {
407 zval *names[7];
408 struct {
409 zval *ps_open;
410 zval *ps_close;
411 zval *ps_read;
412 zval *ps_write;
413 zval *ps_destroy;
414 zval *ps_gc;
415 zval *ps_create_sid;
416 } name;
417 } mod_user_names;
418 int mod_user_implemented;
419 int mod_user_is_open;
420 const struct ps_serializer_struct *serializer;
421 zval *http_session_vars;
422 zend_bool auto_start;
423 zend_bool use_cookies;
424 zend_bool use_only_cookies;
425 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
426 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
427
428 long hash_func;
429#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
430 php_hash_ops *hash_ops;
431#endif
432 long hash_bits_per_character;
433 int send_cookie;
434 int define_sid;
435 zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */
436
437 php_session_rfc1867_progress_54_55_56 *rfc1867_progress;
438 zend_bool rfc1867_enabled; /* session.upload_progress.enabled */
439 zend_bool rfc1867_cleanup; /* session.upload_progress.cleanup */
440 smart_str rfc1867_prefix; /* session.upload_progress.prefix */
441 smart_str rfc1867_name; /* session.upload_progress.name */
442 long rfc1867_freq; /* session.upload_progress.freq */
443 double rfc1867_min_freq; /* session.upload_progress.min_freq */
444
445 zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
446 unsigned char session_data_hash[16]; /* binary MD5 hash length */
447} php_ps_globals_56;
448#endif
449 44
450#ifdef ZTS 45#ifdef ZTS
451static ts_rsrc_id session_globals_id = 0; 46static ts_rsrc_id session_globals_id = 0;
452# if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 6) 47#define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals *, v)
453# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_56 *, v)
454# elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 5)
455# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_55 *, v)
456# elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4)
457# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_54 *, v)
458# elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3)
459# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_53 *, v)
460# elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 2)
461# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_52 *, v)
462# elif (PHP_MAJOR_VERSION == 5)
463# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_50_51 *, v)
464# elif (PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION >= 3)
465# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_43_44 *, v)
466# else
467 UNSUPPORTED PHP VERSION
468# endif
469#else 48#else
470# if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 6) 49static php_ps_globals *session_globals = NULL;
471static php_ps_globals_56 *session_globals = NULL;
472# elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 5)
473static php_ps_globals_55 *session_globals = NULL;
474# elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4)
475static php_ps_globals_54 *session_globals = NULL;
476# elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3)
477static php_ps_globals_53 *session_globals = NULL;
478# elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 2)
479static php_ps_globals_52 *session_globals = NULL;
480# elif (PHP_MAJOR_VERSION == 5)
481static php_ps_globals_50_51 *session_globals = NULL;
482# elif (PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION >= 3)
483static php_ps_globals_43_44 *session_globals = NULL;
484# else
485 UNSUPPORTED PHP VERSION
486# endif
487#define SESSION_G(v) (session_globals->v) 50#define SESSION_G(v) (session_globals->v)
488#endif 51#endif
489 52
490
491ps_serializer *(*suhosin_find_ps_serializer)(char *name TSRMLS_DC) = NULL; 53ps_serializer *(*suhosin_find_ps_serializer)(char *name TSRMLS_DC) = NULL;
492 54
493#define PS_ENCODE_VARS \
494 char *key; \
495 uint key_length; \
496 ulong num_key; \
497 zval **struc;
498
499#define PS_ENCODE_LOOP(code) do { \
500 HashTable *_ht = Z_ARRVAL_P(SESSION_G(http_session_vars)); \
501 int key_type; \
502 \
503 for (zend_hash_internal_pointer_reset(_ht); \
504 (key_type = zend_hash_get_current_key_ex(_ht, &key, &key_length, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTANT; \
505 zend_hash_move_forward(_ht)) { \
506 if (key_type == HASH_KEY_IS_LONG) { \
507 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key); \
508 continue; \
509 } \
510 key_length--; \
511 if (suhosin_get_session_var(key, key_length, &struc TSRMLS_CC) == SUCCESS) { \
512 code; \
513 } \
514 } \
515 } while(0)
516
517static int suhosin_get_session_var(char *name, size_t namelen, zval ***state_var TSRMLS_DC) /* {{{ */ 55static int suhosin_get_session_var(char *name, size_t namelen, zval ***state_var TSRMLS_DC) /* {{{ */
518{ 56{
519 int ret = FAILURE; 57 int ret = FAILURE;
@@ -598,259 +136,6 @@ static void suhosin_send_cookie(TSRMLS_D)
598 *session_send_cookie = 1; 136 *session_send_cookie = 1;
599} 137}
600 138
601void suhosin_get_ipv4(char *buf TSRMLS_DC)
602{
603 char *raddr = suhosin_getenv("REMOTE_ADDR", sizeof("REMOTE_ADDR")-1 TSRMLS_CC);
604 int i;
605
606
607 if (raddr == NULL) {
608 memset(buf, 0, 4);
609 return;
610 }
611
612 for (i=0; i<4; i++) {
613 if (raddr[0] == 0) {
614 buf[i] = 0;
615 } else {
616 buf[i] = strtol(raddr, &raddr, 10);
617 if (raddr[0] == '.') {
618 raddr++;
619 }
620 }
621 }
622}
623
624char *suhosin_encrypt_string(char *str, int len, char *var, int vlen, char *key TSRMLS_DC)
625{
626 int padded_len, i, slen;
627 unsigned char *crypted, *tmp;
628 unsigned int check = 0x13579BDF;
629
630 if (str == NULL) {
631 return NULL;
632 }
633 if (len == 0) {
634 return estrndup("", 0);
635 }
636
637
638 suhosin_aes_gkey(4,8,key TSRMLS_CC);
639
640 padded_len = ((len+15) & ~0xF);
641 crypted = emalloc(16+padded_len+1);
642 memset(crypted, 0xff, 16+padded_len+1);
643 memcpy(crypted+16, str, len+1);
644
645 /* calculate check value */
646 for (i = 0; i<vlen; i++) {
647 check = (check << 3) | (check >> (32-3));
648 check += check << 1;
649 check ^= (unsigned char)var[i];
650 }
651 for (i = 0; i<len; i++) {
652 check = (check << 3) | (check >> (32-3));
653 check += check << 1;
654 check ^= (unsigned char)str[i];
655 }
656
657 /* store ip value */
658 suhosin_get_ipv4((char *)crypted+4 TSRMLS_CC);
659
660 /* store check value */
661 crypted[8] = check & 0xff;
662 crypted[9] = (check >> 8) & 0xff;
663 crypted[10] = (check >> 16) & 0xff;
664 crypted[11] = (check >> 24) & 0xff;
665
666 /* store original length */
667 crypted[12] = len & 0xff;
668 crypted[13] = (len >> 8) & 0xff;
669 crypted[14] = (len >> 16) & 0xff;
670 crypted[15] = (len >> 24) & 0xff;
671
672 for (i=0, tmp=crypted; i<padded_len+16; i+=16, tmp+=16) {
673 if (i > 0) {
674 int j;
675 for (j=0; j<16; j++) tmp[j] ^= tmp[j-16];
676 }
677 suhosin_aes_encrypt((char *)tmp TSRMLS_CC);
678 }
679
680 tmp = php_base64_encode(crypted, padded_len+16, NULL);
681 efree(crypted);
682 slen=strlen((char *)tmp);
683 for (i=0; i<slen; i++) {
684 switch (tmp[i]) {
685 case '/': tmp[i]='-'; break;
686 case '=': tmp[i]='.'; break;
687 case '+': tmp[i]='_'; break;
688 }
689 }
690 return (char *)tmp;
691}
692
693char *suhosin_decrypt_string(char *str, int padded_len, char *var, int vlen, char *key, int *orig_len, int check_ra TSRMLS_DC)
694{
695 int len, i, o_len, invalid = 0;
696 unsigned char *decrypted, *tmp;
697 unsigned int check = 0x13579BDF;
698 char buf[4];
699
700 if (str == NULL) {
701 return NULL;
702 }
703
704 if (padded_len == 0) {
705 if (orig_len) {
706 *orig_len = 0;
707 }
708 return estrndup("", 0);
709 }
710 suhosin_aes_gkey(4,8,key TSRMLS_CC);
711
712 for (i=0; i<padded_len; i++) {
713 switch (str[i]) {
714 case '-': str[i]='/'; break;
715 case '.': str[i]='='; break;
716 case '_': str[i]='+'; break;
717 }
718 }
719
720 decrypted = php_base64_decode((unsigned char *)str, padded_len, &len);
721 if (decrypted == NULL || len < 2*16 || (len % 16) != 0) {
722error_out:
723 if (decrypted != NULL) {
724 efree(decrypted);
725 }
726 if (orig_len) {
727 *orig_len = 0;
728 }
729 return NULL;
730 }
731
732 for (i=len-16, tmp=decrypted+i; i>=0; i-=16, tmp-=16) {
733 suhosin_aes_decrypt((char *)tmp TSRMLS_CC);
734 if (i > 0) {
735 int j;
736 for (j=0; j<16; j++) tmp[j] ^= tmp[j-16];
737 }
738 }
739
740 /* retrieve orig_len */
741 o_len = decrypted[15];
742 o_len <<= 8;
743 o_len |= decrypted[14];
744 o_len <<= 8;
745 o_len |= decrypted[13];
746 o_len <<= 8;
747 o_len |= decrypted[12];
748
749 if (o_len < 0 || o_len > len-16) {
750 goto error_out;
751 }
752
753 /* calculate check value */
754 for (i = 0; i<vlen; i++) {
755 check = (check << 3) | (check >> (32-3));
756 check += check << 1;
757 check ^= (unsigned char)var[i];
758 }
759 for (i = 0; i<o_len; i++) {
760 check = (check << 3) | (check >> (32-3));
761 check += check << 1;
762 check ^= decrypted[16+i];
763 }
764
765 /* check value */
766 invalid = (decrypted[8] != (check & 0xff)) ||
767 (decrypted[9] != ((check >> 8) & 0xff)) ||
768 (decrypted[10] != ((check >> 16) & 0xff)) ||
769 (decrypted[11] != ((check >> 24) & 0xff));
770
771 /* check IP */
772 if (check_ra > 0) {
773 if (check_ra > 4) {
774 check_ra = 4;
775 }
776 suhosin_get_ipv4(&buf[0] TSRMLS_CC);
777 if (memcmp(buf, decrypted+4, check_ra) != 0) {
778 goto error_out;
779 }
780 }
781
782 if (invalid) {
783 goto error_out;
784 }
785
786 if (orig_len) {
787 *orig_len = o_len;
788 }
789
790 memmove(decrypted, decrypted+16, o_len);
791 decrypted[o_len] = 0;
792 /* we do not realloc() here because 16 byte less
793 is simply not worth the overhead */
794 return (char *)decrypted;
795}
796
797char *suhosin_generate_key(char *key, zend_bool ua, zend_bool dr, long raddr, char *cryptkey TSRMLS_DC)
798{
799 char *_ua = NULL;
800 char *_dr = NULL;
801 char *_ra = NULL;
802 suhosin_SHA256_CTX ctx;
803
804 if (ua) {
805 _ua = suhosin_getenv("HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")-1 TSRMLS_CC);
806 }
807
808 if (dr) {
809 _dr = suhosin_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")-1 TSRMLS_CC);
810 }
811
812 if (raddr > 0) {
813 _ra = suhosin_getenv("REMOTE_ADDR", sizeof("REMOTE_ADDR")-1 TSRMLS_CC);
814 }
815
816 SDEBUG("(suhosin_generate_key) KEY: %s - UA: %s - DR: %s - RA: %s", key,_ua,_dr,_ra);
817
818 suhosin_SHA256Init(&ctx);
819 if (key == NULL || *key == 0) {
820 suhosin_SHA256Update(&ctx, (unsigned char*)"D3F4UL7", strlen("D3F4UL7"));
821 } else {
822 suhosin_SHA256Update(&ctx, (unsigned char*)key, strlen(key));
823 }
824 if (_ua) {
825 suhosin_SHA256Update(&ctx, (unsigned char*)_ua, strlen(_ua));
826 }
827 if (_dr) {
828 suhosin_SHA256Update(&ctx, (unsigned char*)_dr, strlen(_dr));
829 }
830 if (_ra) {
831 if (raddr >= 4) {
832 suhosin_SHA256Update(&ctx, (unsigned char*)_ra, strlen(_ra));
833 } else {
834 long dots = 0;
835 char *tmp = _ra;
836
837 while (*tmp) {
838 if (*tmp == '.') {
839 dots++;
840 if (dots == raddr) {
841 break;
842 }
843 }
844 tmp++;
845 }
846 suhosin_SHA256Update(&ctx, (unsigned char*)_ra, tmp-_ra);
847 }
848 }
849 suhosin_SHA256Final((unsigned char *)cryptkey, &ctx);
850 cryptkey[32] = 0; /* uhmm... not really a string */
851
852 return cryptkey;
853}
854 139
855 140
856static 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; 141static 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;
@@ -1152,6 +437,21 @@ void suhosin_unhook_session(TSRMLS_D)
1152 437
1153} 438}
1154 439
440#else /* HAVE_PHP_SESSION */
441
442#warning BUILDING SUHOSIN WITHOUT SESSION SUPPORT
443
444void suhosin_hook_session(TSRMLS_D)
445{
446}
447
448void suhosin_unhook_session(TSRMLS_D)
449{
450}
451
452#endif /* HAVE_PHP_SESSION */
453
454
1155/* 455/*
1156 * Local variables: 456 * Local variables:
1157 * tab-width: 4 457 * tab-width: 4