1 | /* |
2 | +----------------------------------------------------------------------+ |
3 | | PHP Version 5 | |
4 | +----------------------------------------------------------------------+ |
5 | | Copyright (c) 1997-2015 The PHP Group | |
6 | +----------------------------------------------------------------------+ |
7 | | This source file is subject to version 3.01 of the PHP license, | |
8 | | that is bundled with this package in the file LICENSE, and is | |
9 | | available through the world-wide-web at the following url: | |
10 | | http://www.php.net/license/3_01.txt | |
11 | | If you did not receive a copy of the PHP license and are unable to | |
12 | | obtain it through the world-wide-web, please send a note to | |
13 | | license@php.net so we can mail you a copy immediately. | |
14 | +----------------------------------------------------------------------+ |
15 | | Author: Sascha Schumann <sascha@schumann.cx> | |
16 | +----------------------------------------------------------------------+ |
17 | */ |
18 | |
19 | /* $Id$ */ |
20 | |
21 | #ifndef PHP_SESSION_H |
22 | #define PHP_SESSION_H |
23 | |
24 | #include "ext/standard/php_var.h" |
25 | |
26 | #if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH) |
27 | # include "ext/hash/php_hash.h" |
28 | #endif |
29 | |
30 | #define PHP_SESSION_API 20020330 |
31 | |
32 | /* To check php_session_valid_key()/php_session_reset_id() */ |
33 | #define PHP_SESSION_STRICT 1 |
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 | |
43 | /* default create id function */ |
44 | PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); |
45 | |
46 | typedef struct ps_module_struct { |
47 | const char *s_name; |
48 | int (*s_open)(PS_OPEN_ARGS); |
49 | int (*s_close)(PS_CLOSE_ARGS); |
50 | int (*s_read)(PS_READ_ARGS); |
51 | int (*s_write)(PS_WRITE_ARGS); |
52 | int (*s_destroy)(PS_DESTROY_ARGS); |
53 | int (*s_gc)(PS_GC_ARGS); |
54 | char *(*s_create_sid)(PS_CREATE_SID_ARGS); |
55 | } ps_module; |
56 | |
57 | #define PS_GET_MOD_DATA() *mod_data |
58 | #define PS_SET_MOD_DATA(a) *mod_data = (a) |
59 | |
60 | #define PS_OPEN_FUNC(x) int ps_open_##x(PS_OPEN_ARGS) |
61 | #define PS_CLOSE_FUNC(x) int ps_close_##x(PS_CLOSE_ARGS) |
62 | #define PS_READ_FUNC(x) int ps_read_##x(PS_READ_ARGS) |
63 | #define PS_WRITE_FUNC(x) int ps_write_##x(PS_WRITE_ARGS) |
64 | #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) |
65 | #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) |
66 | #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) |
67 | |
68 | #define PS_FUNCS(x) \ |
69 | PS_OPEN_FUNC(x); \ |
70 | PS_CLOSE_FUNC(x); \ |
71 | PS_READ_FUNC(x); \ |
72 | PS_WRITE_FUNC(x); \ |
73 | PS_DESTROY_FUNC(x); \ |
74 | PS_GC_FUNC(x); \ |
75 | PS_CREATE_SID_FUNC(x) |
76 | |
77 | #define PS_MOD(x) \ |
78 | #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ |
79 | ps_delete_##x, ps_gc_##x, php_session_create_id |
80 | |
81 | /* SID creation enabled module handler definitions */ |
82 | #define PS_FUNCS_SID(x) \ |
83 | PS_OPEN_FUNC(x); \ |
84 | PS_CLOSE_FUNC(x); \ |
85 | PS_READ_FUNC(x); \ |
86 | PS_WRITE_FUNC(x); \ |
87 | PS_DESTROY_FUNC(x); \ |
88 | PS_GC_FUNC(x); \ |
89 | PS_CREATE_SID_FUNC(x) |
90 | |
91 | #define PS_MOD_SID(x) \ |
92 | #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ |
93 | ps_delete_##x, ps_gc_##x, ps_create_sid_##x |
94 | |
95 | typedef enum { |
96 | php_session_disabled, |
97 | php_session_none, |
98 | php_session_active |
99 | } php_session_status; |
100 | |
101 | typedef struct _php_session_rfc1867_progress { |
102 | |
103 | size_t sname_len; |
104 | zval sid; |
105 | smart_str key; |
106 | |
107 | long update_step; |
108 | long next_update; |
109 | double next_update_time; |
110 | zend_bool cancel_upload; |
111 | zend_bool apply_trans_sid; |
112 | size_t content_length; |
113 | |
114 | zval *data; /* the array exported to session data */ |
115 | zval *post_bytes_processed; /* data["bytes_processed"] */ |
116 | zval *files; /* data["files"] array */ |
117 | zval *current_file; /* array of currently uploading file */ |
118 | zval *current_file_bytes_processed; |
119 | } php_session_rfc1867_progress; |
120 | |
121 | typedef struct _php_ps_globals { |
122 | char *save_path; |
123 | char *session_name; |
124 | char *id; |
125 | char *extern_referer_chk; |
126 | char *entropy_file; |
127 | char *cache_limiter; |
128 | long entropy_length; |
129 | long cookie_lifetime; |
130 | char *cookie_path; |
131 | char *cookie_domain; |
132 | zend_bool cookie_secure; |
133 | zend_bool cookie_httponly; |
134 | ps_module *mod; |
135 | ps_module *default_mod; |
136 | void *mod_data; |
137 | php_session_status session_status; |
138 | long gc_probability; |
139 | long gc_divisor; |
140 | long gc_maxlifetime; |
141 | int module_number; |
142 | long cache_expire; |
143 | union { |
144 | zval *names[7]; |
145 | struct { |
146 | zval *ps_open; |
147 | zval *ps_close; |
148 | zval *ps_read; |
149 | zval *ps_write; |
150 | zval *ps_destroy; |
151 | zval *ps_gc; |
152 | zval *ps_create_sid; |
153 | } name; |
154 | } mod_user_names; |
155 | int mod_user_implemented; |
156 | int mod_user_is_open; |
157 | const struct ps_serializer_struct *serializer; |
158 | zval *http_session_vars; |
159 | zend_bool auto_start; |
160 | zend_bool use_cookies; |
161 | zend_bool use_only_cookies; |
162 | zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ |
163 | zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ |
164 | |
165 | long hash_func; |
166 | #if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH) |
167 | php_hash_ops *hash_ops; |
168 | #endif |
169 | long hash_bits_per_character; |
170 | int send_cookie; |
171 | int define_sid; |
172 | zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ |
173 | |
174 | php_session_rfc1867_progress *rfc1867_progress; |
175 | zend_bool rfc1867_enabled; /* session.upload_progress.enabled */ |
176 | zend_bool rfc1867_cleanup; /* session.upload_progress.cleanup */ |
177 | smart_str rfc1867_prefix; /* session.upload_progress.prefix */ |
178 | smart_str rfc1867_name; /* session.upload_progress.name */ |
179 | long rfc1867_freq; /* session.upload_progress.freq */ |
180 | double rfc1867_min_freq; /* session.upload_progress.min_freq */ |
181 | |
182 | zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ |
183 | unsigned char session_data_hash[16]; /* binary MD5 hash length */ |
184 | } php_ps_globals; |
185 | |
186 | typedef php_ps_globals zend_ps_globals; |
187 | |
188 | extern zend_module_entry session_module_entry; |
189 | #define phpext_session_ptr &session_module_entry |
190 | |
191 | #ifdef ZTS |
192 | #define PS(v) TSRMG(ps_globals_id, php_ps_globals *, v) |
193 | #else |
194 | #define PS(v) (ps_globals.v) |
195 | #endif |
196 | |
197 | #define PS_SERIALIZER_ENCODE_ARGS char **newstr, int *newlen TSRMLS_DC |
198 | #define PS_SERIALIZER_DECODE_ARGS const char *val, int vallen TSRMLS_DC |
199 | |
200 | typedef struct ps_serializer_struct { |
201 | const char *name; |
202 | int (*encode)(PS_SERIALIZER_ENCODE_ARGS); |
203 | int (*decode)(PS_SERIALIZER_DECODE_ARGS); |
204 | } ps_serializer; |
205 | |
206 | #define PS_SERIALIZER_ENCODE_NAME(x) ps_srlzr_encode_##x |
207 | #define PS_SERIALIZER_DECODE_NAME(x) ps_srlzr_decode_##x |
208 | |
209 | #define PS_SERIALIZER_ENCODE_FUNC(x) \ |
210 | int PS_SERIALIZER_ENCODE_NAME(x)(PS_SERIALIZER_ENCODE_ARGS) |
211 | #define PS_SERIALIZER_DECODE_FUNC(x) \ |
212 | int PS_SERIALIZER_DECODE_NAME(x)(PS_SERIALIZER_DECODE_ARGS) |
213 | |
214 | #define PS_SERIALIZER_FUNCS(x) \ |
215 | PS_SERIALIZER_ENCODE_FUNC(x); \ |
216 | PS_SERIALIZER_DECODE_FUNC(x) |
217 | |
218 | #define PS_SERIALIZER_ENTRY(x) \ |
219 | { #x, PS_SERIALIZER_ENCODE_NAME(x), PS_SERIALIZER_DECODE_NAME(x) } |
220 | |
221 | PHPAPI void session_adapt_url(const char *, size_t, char **, size_t * TSRMLS_DC); |
222 | |
223 | PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC); |
224 | PHPAPI void php_set_session_var(char *name, size_t namelen, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC); |
225 | PHPAPI int php_get_session_var(char *name, size_t namelen, zval ***state_var TSRMLS_DC); |
226 | |
227 | PHPAPI int php_session_register_module(ps_module *); |
228 | |
229 | PHPAPI int php_session_register_serializer(const char *name, |
230 | int (*encode)(PS_SERIALIZER_ENCODE_ARGS), |
231 | int (*decode)(PS_SERIALIZER_DECODE_ARGS)); |
232 | |
233 | PHPAPI void php_session_set_id(char *id TSRMLS_DC); |
234 | PHPAPI void php_session_start(TSRMLS_D); |
235 | |
236 | PHPAPI ps_module *_php_find_ps_module(char *name TSRMLS_DC); |
237 | PHPAPI const ps_serializer *_php_find_ps_serializer(char *name TSRMLS_DC); |
238 | |
239 | PHPAPI int php_session_valid_key(const char *key); |
240 | PHPAPI void php_session_reset_id(TSRMLS_D); |
241 | |
242 | #define PS_ADD_VARL(name,namelen) do { \ |
243 | php_add_session_var(name, namelen TSRMLS_CC); \ |
244 | } while (0) |
245 | |
246 | #define PS_ADD_VAR(name) PS_ADD_VARL(name, strlen(name)) |
247 | |
248 | #define PS_DEL_VARL(name,namelen) do { \ |
249 | if (PS(http_session_vars)) { \ |
250 | zend_hash_del(Z_ARRVAL_P(PS(http_session_vars)), name, namelen+1); \ |
251 | } \ |
252 | } while (0) |
253 | |
254 | |
255 | #define PS_ENCODE_VARS \ |
256 | char *key; \ |
257 | uint key_length; \ |
258 | ulong num_key; \ |
259 | zval **struc; |
260 | |
261 | #define PS_ENCODE_LOOP(code) do { \ |
262 | HashTable *_ht = Z_ARRVAL_P(PS(http_session_vars)); \ |
263 | int key_type; \ |
264 | \ |
265 | for (zend_hash_internal_pointer_reset(_ht); \ |
266 | (key_type = zend_hash_get_current_key_ex(_ht, &key, &key_length, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTENT; \ |
267 | zend_hash_move_forward(_ht)) { \ |
268 | if (key_type == HASH_KEY_IS_LONG) { \ |
269 | php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key); \ |
270 | continue; \ |
271 | } \ |
272 | key_length--; \ |
273 | if (php_get_session_var(key, key_length, &struc TSRMLS_CC) == SUCCESS) { \ |
274 | code; \ |
275 | } \ |
276 | } \ |
277 | } while(0) |
278 | |
279 | PHPAPI ZEND_EXTERN_MODULE_GLOBALS(ps) |
280 | |
281 | void php_session_auto_start(void *data); |
282 | |
283 | #define PS_CLASS_NAME "SessionHandler" |
284 | extern zend_class_entry *php_session_class_entry; |
285 | |
286 | #define PS_IFACE_NAME "SessionHandlerInterface" |
287 | extern zend_class_entry *php_session_iface_entry; |
288 | |
289 | #define PS_SID_IFACE_NAME "SessionIdInterface" |
290 | extern zend_class_entry *php_session_id_iface_entry; |
291 | |
292 | extern PHP_METHOD(SessionHandler, open); |
293 | extern PHP_METHOD(SessionHandler, close); |
294 | extern PHP_METHOD(SessionHandler, read); |
295 | extern PHP_METHOD(SessionHandler, write); |
296 | extern PHP_METHOD(SessionHandler, destroy); |
297 | extern PHP_METHOD(SessionHandler, gc); |
298 | extern PHP_METHOD(SessionHandler, create_sid); |
299 | |
300 | #endif |
301 | |