summaryrefslogtreecommitdiff
path: root/header.c
diff options
context:
space:
mode:
Diffstat (limited to 'header.c')
-rw-r--r--header.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/header.c b/header.c
new file mode 100644
index 0000000..65b2c26
--- /dev/null
+++ b/header.c
@@ -0,0 +1,158 @@
1/*
2 +----------------------------------------------------------------------+
3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007-2016 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 | Authors: Stefan Esser <sesser@sektioneins.de> |
17 | Ben Fuhrmannek <ben.fuhrmannek@sektioneins.de> |
18 +----------------------------------------------------------------------+
19*/
20/*
21 $Id: header.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "php.h"
29#include "php_suhosin7.h"
30#include "SAPI.h"
31
32
33static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers) = NULL;
34
35/* {{{ suhosin_header_handler
36 */
37static int suhosin_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers)
38{
39 int retval = SAPI_HEADER_ADD;
40
41 if (op != SAPI_HEADER_ADD && op != SAPI_HEADER_REPLACE) {
42 goto suhosin_skip_header_handling;
43 }
44
45 if (sapi_header && sapi_header->header) {
46
47 char *tmp = sapi_header->header;
48
49 for (int i = 0; i < sapi_header->header_len; i++, tmp++) {
50 if (tmp[0] == 0) {
51 suhosin_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", suhosin_get_active_function_name());
52 if (!SUHOSIN7_G(simulation)) {
53 sapi_header->header_len = i;
54 }
55 }
56 if (SUHOSIN7_G(allow_multiheader)) {
57 continue;
58 } else if ((tmp[0] == '\r' && (tmp[1] != '\n' || i == 0)) ||
59 (tmp[0] == '\n' && (i == sapi_header->header_len-1 || i == 0 || (tmp[1] != ' ' && tmp[1] != '\t')))) {
60 suhosin_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", suhosin_get_active_function_name());
61 if (!SUHOSIN7_G(simulation)) {
62 sapi_header->header_len = i;
63 tmp[0] = 0;
64 }
65 }
66 }
67 }
68
69 /* Handle a potential cookie */
70
71 if (SUHOSIN7_G(cookie_encrypt) && (strncasecmp("Set-Cookie:", sapi_header->header, sizeof("Set-Cookie:")-1) == 0)) {
72
73 char *start, *end, *rend, *tmp;
74 char *name, *value;
75 int nlen, vlen, len, tlen;
76 char cryptkey[33];
77
78 suhosin_generate_key(SUHOSIN7_G(cookie_cryptkey), SUHOSIN7_G(cookie_cryptua), SUHOSIN7_G(cookie_cryptdocroot), SUHOSIN7_G(cookie_cryptraddr), (char *)&cryptkey TSRMLS_CC);
79 start = estrndup(sapi_header->header, sapi_header->header_len);
80 rend = end = start + sapi_header->header_len;
81
82 tmp = memchr(start, ';', end-start);
83 if (tmp != NULL) {
84 end = tmp;
85 }
86
87 tmp = start + sizeof("Set-Cookie:") - 1;
88 while (tmp < end && isspace(*tmp)) {
89 tmp++;
90 }
91 name = tmp;
92 nlen = end-name;
93 tmp = memchr(name, '=', nlen);
94 if (tmp == NULL) {
95 value = end;
96 } else {
97 value = tmp+1;
98 nlen = tmp-name;
99 }
100 vlen = end-value;
101
102 zend_string *zs_val = suhosin_encrypt_single_cookie(name, nlen, value, vlen, (char *)cryptkey);
103
104 len = sizeof("Set-Cookie: ")-1 + nlen + 1 + ZSTR_LEN(zs_val) + rend-end;
105 tmp = emalloc(len + 1);
106 tlen = sprintf(tmp, "Set-Cookie: %.*s=%s", nlen, name, ZSTR_VAL(zs_val));
107 memcpy(tmp + tlen, end, rend-end);
108 tmp[len] = 0;
109
110 efree(sapi_header->header);
111 // efree(value);
112 zend_string_release(zs_val);
113 efree(start);
114
115 sapi_header->header = tmp;
116 sapi_header->header_len = len;
117 }
118
119suhosin_skip_header_handling:
120 /* If existing call the sapi header handler */
121 if (orig_header_handler) {
122 retval = orig_header_handler(sapi_header, op, sapi_headers TSRMLS_CC);
123 }
124
125 return retval;
126}
127/* }}} */
128
129
130/* {{{ suhosin_hook_header_handler
131 */
132void suhosin_hook_header_handler()
133{
134 if (orig_header_handler == NULL) {
135 orig_header_handler = sapi_module.header_handler;
136 sapi_module.header_handler = suhosin_header_handler;
137 }
138}
139/* }}} */
140
141/* {{{ suhosin_unhook_header_handler
142 */
143void suhosin_unhook_header_handler()
144{
145 sapi_module.header_handler = orig_header_handler;
146 orig_header_handler = NULL;
147}
148/* }}} */
149
150
151/*
152 * Local variables:
153 * tab-width: 4
154 * c-basic-offset: 4
155 * End:
156 * vim600: noet sw=4 ts=4 fdm=marker
157 * vim<600: noet sw=4 ts=4
158 */