summaryrefslogtreecommitdiff
path: root/src/sp_utils.c
diff options
context:
space:
mode:
authorThibault "bui" Koechlin2017-12-28 17:04:06 +0100
committerjvoisin2017-12-28 17:04:06 +0100
commit9f5e8d12f05fb24c915a5266a1e908a75c8aed08 (patch)
tree9160075ea943c7fd29a3923f844a0ac0d6b8b457 /src/sp_utils.c
parent62c48bf9a85e0294b7b32cea438e904e1cd50669 (diff)
Clang-format pass
- `clang-format --style="{BasedOnStyle: google, SortIncludes: false}" -i snuffleu*.c sp_*.c sp_*.h` - Update the documentation accordingly
Diffstat (limited to 'src/sp_utils.c')
-rw-r--r--src/sp_utils.c132
1 files changed, 68 insertions, 64 deletions
diff --git a/src/sp_utils.c b/src/sp_utils.c
index 3fe2e44..8a1ed87 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -17,7 +17,7 @@ static inline void _sp_log_err(const char* fmt, ...) {
17 php_log_err(msg); 17 php_log_err(msg);
18} 18}
19 19
20void sp_log_msg(char const *feature, char const *level, const char* fmt, ...) { 20void sp_log_msg(char const* feature, char const* level, const char* fmt, ...) {
21 char* msg; 21 char* msg;
22 va_list args; 22 va_list args;
23 23
@@ -25,9 +25,9 @@ void sp_log_msg(char const *feature, char const *level, const char* fmt, ...) {
25 vspprintf(&msg, 0, fmt, args); 25 vspprintf(&msg, 0, fmt, args);
26 va_end(args); 26 va_end(args);
27 27
28 char const * const client_ip = getenv("REMOTE_ADDR"); 28 char const* const client_ip = getenv("REMOTE_ADDR");
29 _sp_log_err("[snuffleupagus][%s][%s][%s] %s", client_ip?client_ip:"0.0.0.0", 29 _sp_log_err("[snuffleupagus][%s][%s][%s] %s",
30 feature, level, msg); 30 client_ip ? client_ip : "0.0.0.0", feature, level, msg);
31} 31}
32 32
33zend_always_inline int is_regexp_matching(const pcre* regexp, const char* str) { 33zend_always_inline int is_regexp_matching(const pcre* regexp, const char* str) {
@@ -38,7 +38,7 @@ zend_always_inline int is_regexp_matching(const pcre* regexp, const char* str) {
38 assert(NULL != str); 38 assert(NULL != str);
39 39
40 ret = sp_pcre_exec(regexp, NULL, str, strlen(str), 0, 0, vec, 40 ret = sp_pcre_exec(regexp, NULL, str, strlen(str), 0, 0, vec,
41 sizeof(vec)/sizeof(int)); 41 sizeof(vec) / sizeof(int));
42 42
43 if (ret < 0) { 43 if (ret < 0) {
44 if (ret != PCRE_ERROR_NOMATCH) { 44 if (ret != PCRE_ERROR_NOMATCH) {
@@ -58,7 +58,8 @@ int compute_hash(const char* const filename, char* file_hash) {
58 php_stream* stream = 58 php_stream* stream =
59 php_stream_open_wrapper(filename, "rb", REPORT_ERRORS, NULL); 59 php_stream_open_wrapper(filename, "rb", REPORT_ERRORS, NULL);
60 if (!stream) { 60 if (!stream) {
61 sp_log_err("hash_computation", "Can not open the file %s to compute its hash.\n", filename); 61 sp_log_err("hash_computation",
62 "Can not open the file %s to compute its hash.\n", filename);
62 return FAILURE; 63 return FAILURE;
63 } 64 }
64 65
@@ -73,14 +74,13 @@ int compute_hash(const char* const filename, char* file_hash) {
73} 74}
74 75
75static int construct_filename(char* filename, const char* folder, 76static int construct_filename(char* filename, const char* folder,
76 const char* textual) { 77 const char* textual) {
77 PHP_SHA256_CTX context; 78 PHP_SHA256_CTX context;
78 unsigned char digest[SHA256_SIZE] = {0}; 79 unsigned char digest[SHA256_SIZE] = {0};
79 char strhash[65] = {0}; 80 char strhash[65] = {0};
80 81
81 if (-1 == mkdir(folder, 0700) && errno != EEXIST) { 82 if (-1 == mkdir(folder, 0700) && errno != EEXIST) {
82 sp_log_err("request_logging", "Unable to create the folder '%s'.", 83 sp_log_err("request_logging", "Unable to create the folder '%s'.", folder);
83 folder);
84 return -1; 84 return -1;
85 } 85 }
86 86
@@ -88,10 +88,10 @@ static int construct_filename(char* filename, const char* folder,
88 * as filename, in order to only have one dump per rule, to migitate 88 * as filename, in order to only have one dump per rule, to migitate
89 * DoS attacks. */ 89 * DoS attacks. */
90 PHP_SHA256Init(&context); 90 PHP_SHA256Init(&context);
91 PHP_SHA256Update(&context, (const unsigned char *) textual, strlen(textual)); 91 PHP_SHA256Update(&context, (const unsigned char*)textual, strlen(textual));
92 PHP_SHA256Final(digest, &context); 92 PHP_SHA256Final(digest, &context);
93 make_digest_ex(strhash, digest, SHA256_SIZE); 93 make_digest_ex(strhash, digest, SHA256_SIZE);
94 snprintf(filename, MAX_FOLDER_LEN-1, "%s/sp_dump.%s", folder, strhash); 94 snprintf(filename, MAX_FOLDER_LEN - 1, "%s/sp_dump.%s", folder, strhash);
95 95
96 return 0; 96 return 0;
97} 97}
@@ -106,14 +106,14 @@ int sp_log_request(const char* folder, const char* text_repr) {
106 const int key; 106 const int key;
107 } zones[] = {{"GET", TRACK_VARS_GET}, {"POST", TRACK_VARS_POST}, 107 } zones[] = {{"GET", TRACK_VARS_GET}, {"POST", TRACK_VARS_POST},
108 {"COOKIE", TRACK_VARS_COOKIE}, {"SERVER", TRACK_VARS_SERVER}, 108 {"COOKIE", TRACK_VARS_COOKIE}, {"SERVER", TRACK_VARS_SERVER},
109 {"ENV", TRACK_VARS_ENV}, {NULL, 0}}; 109 {"ENV", TRACK_VARS_ENV}, {NULL, 0}};
110 110
111 if (0 != construct_filename(filename, folder, text_repr)) { 111 if (0 != construct_filename(filename, folder, text_repr)) {
112 return -1; 112 return -1;
113 } 113 }
114 if (NULL == (file = fopen(filename, "w+"))) { 114 if (NULL == (file = fopen(filename, "w+"))) {
115 sp_log_err("request_logging", "Unable to open %s: %s", filename, 115 sp_log_err("request_logging", "Unable to open %s: %s", filename,
116 strerror(errno)); 116 strerror(errno));
117 return -1; 117 return -1;
118 } 118 }
119 119
@@ -147,7 +147,7 @@ int sp_log_request(const char* folder, const char* text_repr) {
147 return 0; 147 return 0;
148} 148}
149 149
150static char *zv_str_to_char(zval *zv) { 150static char* zv_str_to_char(zval* zv) {
151 zval copy; 151 zval copy;
152 152
153 ZVAL_ZVAL(&copy, zv, 1, 0); 153 ZVAL_ZVAL(&copy, zv, 1, 0);
@@ -159,7 +159,6 @@ static char *zv_str_to_char(zval *zv) {
159 return estrdup(Z_STRVAL(copy)); 159 return estrdup(Z_STRVAL(copy));
160} 160}
161 161
162
163char* sp_convert_to_string(zval* zv) { 162char* sp_convert_to_string(zval* zv) {
164 switch (Z_TYPE_P(zv)) { 163 switch (Z_TYPE_P(zv)) {
165 case IS_FALSE: 164 case IS_FALSE:
@@ -169,18 +168,18 @@ char* sp_convert_to_string(zval* zv) {
169 case IS_NULL: 168 case IS_NULL:
170 return estrdup("NULL"); 169 return estrdup("NULL");
171 case IS_LONG: { 170 case IS_LONG: {
172 char *msg; 171 char* msg;
173 spprintf(&msg, 0, ZEND_LONG_FMT, Z_LVAL_P(zv)); 172 spprintf(&msg, 0, ZEND_LONG_FMT, Z_LVAL_P(zv));
174 return msg; 173 return msg;
175 } 174 }
176 case IS_DOUBLE: { 175 case IS_DOUBLE: {
177 char *msg; 176 char* msg;
178 spprintf(&msg, 0, "%f", Z_DVAL_P(zv)); 177 spprintf(&msg, 0, "%f", Z_DVAL_P(zv));
179 return msg; 178 return msg;
180 } 179 }
181 case IS_STRING:{ 180 case IS_STRING: {
182 return zv_str_to_char(zv); 181 return zv_str_to_char(zv);
183 } 182 }
184 case IS_OBJECT: 183 case IS_OBJECT:
185 return estrdup("OBJECT"); 184 return estrdup("OBJECT");
186 case IS_ARRAY: 185 case IS_ARRAY:
@@ -212,31 +211,32 @@ void sp_log_disable(const char* restrict path, const char* restrict arg_name,
212 const int sim = config_node->simulation; 211 const int sim = config_node->simulation;
213 if (arg_name) { 212 if (arg_name) {
214 if (alias) { 213 if (alias) {
215 sp_log_msg("disabled_function", sim?SP_LOG_SIMULATION:SP_LOG_DROP, 214 sp_log_msg(
215 "disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP,
216 "The call to the function '%s' in %s:%d has been disabled, " 216 "The call to the function '%s' in %s:%d has been disabled, "
217 "because its argument '%s' content (%s) matched the rule '%s'.", 217 "because its argument '%s' content (%s) matched the rule '%s'.",
218 path, zend_get_executed_filename(TSRMLS_C), 218 path, zend_get_executed_filename(TSRMLS_C),
219 zend_get_executed_lineno(TSRMLS_C), arg_name, arg_value?arg_value:"?",
220 alias);
221 } else {
222 sp_log_msg("disabled_function", sim?SP_LOG_SIMULATION:SP_LOG_DROP,
223 "The call to the function '%s' in %s:%d has been disabled, "
224 "because its argument '%s' content (%s) matched a rule.",
225 path, zend_get_executed_filename(TSRMLS_C),
226 zend_get_executed_lineno(TSRMLS_C), arg_name, 219 zend_get_executed_lineno(TSRMLS_C), arg_name,
227 arg_value?arg_value:"?"); 220 arg_value ? arg_value : "?", alias);
221 } else {
222 sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP,
223 "The call to the function '%s' in %s:%d has been disabled, "
224 "because its argument '%s' content (%s) matched a rule.",
225 path, zend_get_executed_filename(TSRMLS_C),
226 zend_get_executed_lineno(TSRMLS_C), arg_name,
227 arg_value ? arg_value : "?");
228 } 228 }
229 } else { 229 } else {
230 if (alias) { 230 if (alias) {
231 sp_log_msg("disabled_function", sim?SP_LOG_SIMULATION:SP_LOG_DROP, 231 sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP,
232 "The call to the function '%s' in %s:%d has been disabled, " 232 "The call to the function '%s' in %s:%d has been disabled, "
233 "because of the the rule '%s'.",path, 233 "because of the the rule '%s'.",
234 zend_get_executed_filename(TSRMLS_C), 234 path, zend_get_executed_filename(TSRMLS_C),
235 zend_get_executed_lineno(TSRMLS_C), alias); 235 zend_get_executed_lineno(TSRMLS_C), alias);
236 } else { 236 } else {
237 sp_log_msg("disabled_function", sim?SP_LOG_SIMULATION:SP_LOG_DROP, 237 sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP,
238 "The call to the function '%s' in %s:%d has been disabled.", 238 "The call to the function '%s' in %s:%d has been disabled.",
239 path, zend_get_executed_filename(TSRMLS_C), 239 path, zend_get_executed_filename(TSRMLS_C),
240 zend_get_executed_lineno(TSRMLS_C)); 240 zend_get_executed_lineno(TSRMLS_C));
241 } 241 }
242 } 242 }
@@ -252,17 +252,20 @@ void sp_log_disable_ret(const char* restrict path,
252 const char* alias = config_node->alias; 252 const char* alias = config_node->alias;
253 const int sim = config_node->simulation; 253 const int sim = config_node->simulation;
254 if (alias) { 254 if (alias) {
255 sp_log_msg("disabled_function", sim?SP_LOG_SIMULATION:SP_LOG_DROP, 255 sp_log_msg(
256 "disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP,
256 "The execution has been aborted in %s:%d, " 257 "The execution has been aborted in %s:%d, "
257 "because the function '%s' returned '%s', which matched the rule '%s'.", 258 "because the function '%s' returned '%s', which matched the rule '%s'.",
258 zend_get_executed_filename(TSRMLS_C), 259 zend_get_executed_filename(TSRMLS_C),
259 zend_get_executed_lineno(TSRMLS_C), path, ret_value?ret_value:"?", alias); 260 zend_get_executed_lineno(TSRMLS_C), path, ret_value ? ret_value : "?",
261 alias);
260 } else { 262 } else {
261 sp_log_msg("disabled_function", sim?SP_LOG_SIMULATION:SP_LOG_DROP, 263 sp_log_msg(
264 "disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP,
262 "The execution has been aborted in %s:%d, " 265 "The execution has been aborted in %s:%d, "
263 "because the return value (%s) of the function '%s' matched a rule.", 266 "because the return value (%s) of the function '%s' matched a rule.",
264 zend_get_executed_filename(TSRMLS_C), 267 zend_get_executed_filename(TSRMLS_C),
265 zend_get_executed_lineno(TSRMLS_C), ret_value?ret_value:"?", path); 268 zend_get_executed_lineno(TSRMLS_C), ret_value ? ret_value : "?", path);
266 } 269 }
267 if (dump) { 270 if (dump) {
268 sp_log_request(dump, config_node->textual_representation); 271 sp_log_request(dump, config_node->textual_representation);
@@ -276,17 +279,17 @@ bool sp_match_array_key(const zval* zv, const char* to_match, const pcre* rx) {
276 ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(zv), idx, key) { 279 ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(zv), idx, key) {
277 if (key) { 280 if (key) {
278 if (sp_match_value(ZSTR_VAL(key), to_match, rx)) { 281 if (sp_match_value(ZSTR_VAL(key), to_match, rx)) {
279 return true; 282 return true;
280 } 283 }
281 } else { 284 } else {
282 char *idx_str = NULL; 285 char* idx_str = NULL;
283 286
284 // Could use a log. 287 // Could use a log.
285 idx_str = emalloc(snprintf(NULL, 0, "%lu", idx)); 288 idx_str = emalloc(snprintf(NULL, 0, "%lu", idx));
286 sprintf(idx_str, "%lu", idx); 289 sprintf(idx_str, "%lu", idx);
287 if (sp_match_value(idx_str, to_match, rx)) { 290 if (sp_match_value(idx_str, to_match, rx)) {
288 efree(idx_str); 291 efree(idx_str);
289 return true; 292 return true;
290 } 293 }
291 efree(idx_str); 294 efree(idx_str);
292 } 295 }
@@ -295,17 +298,18 @@ bool sp_match_array_key(const zval* zv, const char* to_match, const pcre* rx) {
295 return false; 298 return false;
296} 299}
297 300
298bool sp_match_array_value(const zval* arr, const char* to_match, const pcre* rx) { 301bool sp_match_array_value(const zval* arr, const char* to_match,
302 const pcre* rx) {
299 zval* value; 303 zval* value;
300 304
301 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), value) { 305 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), value) {
302 if (Z_TYPE_P(value) != IS_ARRAY) { 306 if (Z_TYPE_P(value) != IS_ARRAY) {
303 char *value_str = sp_convert_to_string(value); 307 char* value_str = sp_convert_to_string(value);
304 if (sp_match_value(value_str, to_match, rx)) { 308 if (sp_match_value(value_str, to_match, rx)) {
305 efree(value_str); 309 efree(value_str);
306 return true; 310 return true;
307 } else { 311 } else {
308 efree (value_str); 312 efree(value_str);
309 } 313 }
310 } else if (sp_match_array_value(value, to_match, rx)) { 314 } else if (sp_match_array_value(value, to_match, rx)) {
311 return true; 315 return true;
@@ -315,18 +319,17 @@ bool sp_match_array_value(const zval* arr, const char* to_match, const pcre* rx)
315 return false; 319 return false;
316} 320}
317 321
318
319int hook_function(const char* original_name, HashTable* hook_table, 322int hook_function(const char* original_name, HashTable* hook_table,
320 void (*new_function)(INTERNAL_FUNCTION_PARAMETERS), 323 void (*new_function)(INTERNAL_FUNCTION_PARAMETERS),
321 bool hook_execution_table) { 324 bool hook_execution_table) {
322 zend_internal_function* func; 325 zend_internal_function* func;
323 HashTable *ht = hook_execution_table==true?EG(function_table):CG(function_table); 326 HashTable* ht =
327 hook_execution_table == true ? EG(function_table) : CG(function_table);
324 328
325 /* The `mb` module likes to hook functions, like strlen->mb_strlen, 329 /* The `mb` module likes to hook functions, like strlen->mb_strlen,
326 * so we have to hook both of them. */ 330 * so we have to hook both of them. */
327 331
328 if ((func = zend_hash_str_find_ptr(ht, 332 if ((func = zend_hash_str_find_ptr(ht, VAR_AND_LEN(original_name)))) {
329 VAR_AND_LEN(original_name)))) {
330 if (func->handler == new_function) { 333 if (func->handler == new_function) {
331 return SUCCESS; 334 return SUCCESS;
332 } 335 }
@@ -340,7 +343,7 @@ int hook_function(const char* original_name, HashTable* hook_table,
340 VAR_AND_LEN(original_name), 343 VAR_AND_LEN(original_name),
341 func->handler) == NULL) { 344 func->handler) == NULL) {
342 sp_log_err("function_pointer_saving", 345 sp_log_err("function_pointer_saving",
343 "Could not save function pointer for %s", original_name); 346 "Could not save function pointer for %s", original_name);
344 return FAILURE; 347 return FAILURE;
345 } else { 348 } else {
346 func->handler = new_function; 349 func->handler = new_function;
@@ -349,9 +352,9 @@ int hook_function(const char* original_name, HashTable* hook_table,
349 352
350 if (0 == strncmp(original_name, "mb_", 3)) { 353 if (0 == strncmp(original_name, "mb_", 3)) {
351 CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; 354 CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN;
352 if (zend_hash_str_find(ht, 355 if (zend_hash_str_find(ht, VAR_AND_LEN(original_name + 3))) {
353 VAR_AND_LEN(original_name + 3))) { 356 hook_function(original_name + 3, hook_table, new_function,
354 hook_function(original_name + 3, hook_table, new_function, hook_execution_table); 357 hook_execution_table);
355 } 358 }
356 } else { // TODO this can be moved somewhere else to gain some marginal perfs 359 } else { // TODO this can be moved somewhere else to gain some marginal perfs
357 CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; 360 CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN;
@@ -370,13 +373,14 @@ int hook_regexp(const pcre* regexp, HashTable* hook_table,
370 void (*new_function)(INTERNAL_FUNCTION_PARAMETERS), 373 void (*new_function)(INTERNAL_FUNCTION_PARAMETERS),
371 bool hook_execution_table) { 374 bool hook_execution_table) {
372 zend_string* key; 375 zend_string* key;
373 HashTable *ht = hook_execution_table==true?EG(function_table):CG(function_table); 376 HashTable* ht =
377 hook_execution_table == true ? EG(function_table) : CG(function_table);
374 378
375 ZEND_HASH_FOREACH_STR_KEY(ht, key) { 379 ZEND_HASH_FOREACH_STR_KEY(ht, key) {
376 if (key) { 380 if (key) {
377 int vec[30]; 381 int vec[30];
378 int ret = sp_pcre_exec(regexp, NULL, key->val, key->len, 0, 0, vec, 382 int ret = sp_pcre_exec(regexp, NULL, key->val, key->len, 0, 0, vec,
379 sizeof(vec)/sizeof(int)); 383 sizeof(vec) / sizeof(int));
380 if (ret < 0) { /* Error or no match*/ 384 if (ret < 0) { /* Error or no match*/
381 if (PCRE_ERROR_NOMATCH != ret) { 385 if (PCRE_ERROR_NOMATCH != ret) {
382 sp_log_err("pcre", "Runtime error with pcre, error code: %d", ret); 386 sp_log_err("pcre", "Runtime error with pcre, error code: %d", ret);