summaryrefslogtreecommitdiff
path: root/src/sp_session.c
diff options
context:
space:
mode:
authorkkadosh2018-05-29 19:34:16 +0000
committerjvoisin2018-05-29 19:34:16 +0000
commit7832438b7abedf567ce6376f99949f419abcdff1 (patch)
tree560e43918d1dc36ce4cf760a5b27aed0c563bc1c /src/sp_session.c
parent9eebe8c67e03e3041d454ea28e93996f7a67740b (diff)
Support session encryption
Implement session encryption.
Diffstat (limited to 'src/sp_session.c')
-rw-r--r--src/sp_session.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/sp_session.c b/src/sp_session.c
new file mode 100644
index 0000000..4085007
--- /dev/null
+++ b/src/sp_session.c
@@ -0,0 +1,159 @@
1#include "php_snuffleupagus.h"
2#include "ext/session/php_session.h"
3
4ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus);
5
6#ifdef ZTS
7static ts_rsrc_id session_globals_id = 0;
8#define SESSION_G(v) ZEND_TSRMG(session_globals_id, php_ps_globals *, v)
9#ifdef COMPILE_DL_SESSION
10ZEND_TSRMLS_CACHE_EXTERN();
11#endif
12#else
13#define SESSION_G(v) (ps_globals.v)
14#endif
15
16static php_ps_globals *session_globals = NULL;
17static ps_module *s_module;
18static ps_module *s_original_mod;
19static int (*old_s_read)(PS_READ_ARGS);
20static int (*old_s_write)(PS_WRITE_ARGS);
21static int (*previous_sessionRINIT)(INIT_FUNC_ARGS) = NULL;
22static ZEND_INI_MH((*old_OnUpdateSaveHandler)) = NULL;
23
24
25static int sp_hook_s_read(PS_READ_ARGS) {
26 int r = old_s_read(mod_data, key, val, maxlifetime);
27 if (r == SUCCESS && SNUFFLEUPAGUS_G(config).config_session->encrypt &&
28 val != NULL && *val != NULL && ZSTR_LEN(*val)) {
29 zend_string *orig_val = *val;
30 zval val_zval;
31 ZVAL_PSTRINGL(&val_zval, ZSTR_VAL(*val), ZSTR_LEN(*val));
32
33 int ret = decrypt_zval(
34 &val_zval, SNUFFLEUPAGUS_G(config).config_session->simulation,
35 NULL);
36 if (0 != ret) {
37 if (SNUFFLEUPAGUS_G(config).config_session->simulation) {
38 return ret;
39 } else {
40 sp_terminate();
41 }
42 }
43
44 *val = zend_string_dup(val_zval.value.str, 0);
45 if (*val == NULL) {
46 *val = ZSTR_EMPTY_ALLOC();
47 }
48 zend_string_release(orig_val);
49 }
50
51 return r;
52}
53
54
55static int sp_hook_s_write(PS_WRITE_ARGS) {
56 if (ZSTR_LEN(val) > 0 &&
57 SNUFFLEUPAGUS_G(config).config_session->encrypt) {
58 zend_string *new_val = encrypt_zval(ZSTR_VAL(val), ZSTR_LEN(val));
59 return old_s_write(mod_data, key, new_val, maxlifetime);
60 }
61 return old_s_write(mod_data, key, val, maxlifetime);
62}
63
64static void sp_hook_session_module() {
65 ps_module *old_mod = SESSION_G(mod);
66 ps_module *mod;
67
68 if (old_mod == NULL || s_module == old_mod) {
69 return;
70 }
71
72 if (s_module == NULL) {
73 s_module = mod = malloc(sizeof(ps_module));
74 if (mod == NULL) {
75 return;
76 }
77 }
78
79 s_original_mod = old_mod;
80
81 mod = s_module;
82 memcpy(mod, old_mod, sizeof(ps_module));
83
84 old_s_read = mod->s_read;
85 mod->s_read = sp_hook_s_read;
86
87 old_s_write = mod->s_write;
88 mod->s_write = sp_hook_s_write;
89
90 SESSION_G(mod) = mod;
91}
92
93static PHP_INI_MH(sp_OnUpdateSaveHandler) {
94 if (stage == PHP_INI_STAGE_RUNTIME &&
95 SESSION_G(session_status) == php_session_none &&
96 s_original_mod &&
97 zend_string_equals_literal(new_value, "user") == 0 &&
98 strcmp(((ps_module *)s_original_mod)->s_name, "user") ==
99 0) {
100 return SUCCESS;
101 }
102
103 SESSION_G(mod) = s_original_mod;
104
105 int r = old_OnUpdateSaveHandler(entry, new_value, mh_arg1, mh_arg2, mh_arg3,
106 stage);
107
108 sp_hook_session_module();
109
110 return r;
111}
112
113static int sp_hook_session_RINIT(INIT_FUNC_ARGS) {
114 if (SESSION_G(mod) == NULL) {
115 zend_ini_entry *ini_entry;
116 if ((ini_entry = zend_hash_str_find_ptr(
117 EG(ini_directives), ZEND_STRL("session.save_handler")))) {
118 if (ini_entry->value) {
119 sp_OnUpdateSaveHandler(NULL, ini_entry->value, NULL, NULL, NULL, 0);
120 }
121 }
122 }
123 return previous_sessionRINIT(INIT_FUNC_ARGS_PASSTHRU);
124}
125
126void hook_session() {
127 zend_module_entry *module;
128
129 if ((module = zend_hash_str_find_ptr(&module_registry,
130 ZEND_STRL("session"))) == NULL) {
131 return;
132 }
133
134#ifdef ZTS
135 if (session_globals_id == 0) {
136 session_globals_id = *module->globals_id_ptr;
137 }
138#else
139 if (session_globals == NULL) {
140 session_globals = module->globals_ptr;
141 }
142#endif
143 if (old_OnUpdateSaveHandler != NULL) {
144 return;
145 }
146
147 previous_sessionRINIT = module->request_startup_func;
148 module->request_startup_func = sp_hook_session_RINIT;
149
150 zend_ini_entry *ini_entry;
151 if ((ini_entry = zend_hash_str_find_ptr(
152 EG(ini_directives), ZEND_STRL("session.save_handler"))) != NULL) {
153 old_OnUpdateSaveHandler = ini_entry->on_modify;
154 ini_entry->on_modify = sp_OnUpdateSaveHandler;
155 }
156 s_module = NULL;
157
158 sp_hook_session_module();
159} \ No newline at end of file