summaryrefslogtreecommitdiff
path: root/src/sp_upload_validation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sp_upload_validation.c')
-rw-r--r--src/sp_upload_validation.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/sp_upload_validation.c b/src/sp_upload_validation.c
new file mode 100644
index 0000000..bbd7eae
--- /dev/null
+++ b/src/sp_upload_validation.c
@@ -0,0 +1,92 @@
1#include "php_snuffleupagus.h"
2#include "rfc1867.h"
3
4ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus);
5
6#define EFREE_3(env) \
7 for (size_t i = 0; i < 4; i++) { \
8 efree(env[i]); \
9 }
10
11void hook_upload() {
12 sp_rfc1867_orig_callback = php_rfc1867_callback;
13 php_rfc1867_callback = sp_rfc1867_callback;
14}
15
16int sp_rfc1867_callback(unsigned int event, void *event_data, void **extra) {
17 int retval = SUCCESS;
18
19 if (sp_rfc1867_orig_callback) {
20 retval = sp_rfc1867_orig_callback(event, event_data, extra);
21 }
22
23 if (event == MULTIPART_EVENT_END) {
24 zend_string *file_key __attribute__((unused)) = NULL;
25 zval *file;
26 pid_t pid;
27
28 sp_log_debug(
29 "Got %d files",
30 zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_FILES])));
31
32 ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL(PG(http_globals)[TRACK_VARS_FILES]),
33 file_key, file) { // for each uploaded file
34
35 char *filename =
36 Z_STRVAL_P(zend_hash_str_find(Z_ARRVAL_P(file), "name", 4));
37 char *tmp_name =
38 Z_STRVAL_P(zend_hash_str_find(Z_ARRVAL_P(file), "tmp_name", 8));
39 size_t filesize =
40 Z_LVAL_P(zend_hash_str_find(Z_ARRVAL_P(file), "size", 4));
41 char *cmd[3] = {0};
42 char *env[5] = {0};
43
44 sp_log_debug("Filename: %s\nTmpname: %s\nSize: %d\nError: %d\nScript: %s",
45 filename, tmp_name, filesize,
46 Z_LVAL_P(zend_hash_str_find(Z_ARRVAL_P(file), "error", 5)),
47 SNUFFLEUPAGUS_G(config).config_upload_validation->script);
48
49 cmd[0] = SNUFFLEUPAGUS_G(config).config_upload_validation->script;
50 cmd[1] = tmp_name;
51 cmd[2] = NULL;
52
53 spprintf(&env[0], 0, "SP_FILENAME=%s", filename);
54 spprintf(&env[1], 0, "SP_REMOTE_ADDR=%s", sp_getenv("REMOTE_ADDR"));
55 spprintf(&env[2], 0, "SP_CURRENT_FILE=%s",
56 zend_get_executed_filename(TSRMLS_C));
57 spprintf(&env[3], 0, "SP_FILESIZE=%zu", filesize);
58 env[4] = NULL;
59
60 if ((pid = fork()) == 0) {
61 if (execve(SNUFFLEUPAGUS_G(config).config_upload_validation->script,
62 cmd, env) == -1) {
63 sp_log_err("upload_validation", "Could not call '%s' : %s",
64 SNUFFLEUPAGUS_G(config).config_upload_validation->script,
65 strerror(errno));
66 EFREE_3(env);
67 exit(1);
68 }
69 } else if (pid == -1) {
70 sp_log_err("upload_validation", "Could not fork process : %s\n",
71 strerror(errno));
72 EFREE_3(env);
73 continue;
74 }
75
76 EFREE_3(env);
77 int waitstatus;
78 wait(&waitstatus);
79 if (WEXITSTATUS(waitstatus) != 0) { // Nope
80 char *uri = sp_getenv("REQUEST_URI");
81 int sim = SNUFFLEUPAGUS_G(config).config_upload_validation->simulation;
82 sp_log_msg("upload_valiation", sim?LOG_NOTICE:LOG_DROP,
83 "The upload of %s on %s was rejected.", filename, uri?uri:"?");
84 if (!SNUFFLEUPAGUS_G(config).config_upload_validation->simulation) {
85 zend_bailout();
86 }
87 }
88 }
89 ZEND_HASH_FOREACH_END();
90 }
91 return retval;
92}