diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/config.m4 | 2 | ||||
| -rw-r--r-- | src/php_snuffleupagus.h | 1 | ||||
| -rw-r--r-- | src/snuffleupagus.c | 15 | ||||
| -rw-r--r-- | src/sp_config.c | 21 | ||||
| -rw-r--r-- | src/sp_config.h | 12 | ||||
| -rw-r--r-- | src/sp_config_keywords.c | 20 | ||||
| -rw-r--r-- | src/sp_config_keywords.h | 1 | ||||
| -rw-r--r-- | src/sp_wrapper.c | 70 | ||||
| -rw-r--r-- | src/sp_wrapper.h | 8 | ||||
| -rw-r--r-- | src/tests/config/config_stream_wrapper.ini | 1 | ||||
| -rw-r--r-- | src/tests/config/config_stream_wrapper_register.ini | 1 | ||||
| -rw-r--r-- | src/tests/stream_wrapper.phpt | 31 | ||||
| -rw-r--r-- | src/tests/stream_wrapper_register.phpt | 25 | ||||
| -rw-r--r-- | src/tests/stream_wrapper_restore.phpt | 17 |
14 files changed, 216 insertions, 9 deletions
diff --git a/src/config.m4 b/src/config.m4 index 0165f87..52b6d04 100644 --- a/src/config.m4 +++ b/src/config.m4 | |||
| @@ -6,7 +6,7 @@ sources="$sources sp_unserialize.c sp_utils.c sp_disable_xxe.c sp_list.c" | |||
| 6 | sources="$sources sp_disabled_functions.c sp_execute.c sp_upload_validation.c" | 6 | sources="$sources sp_disabled_functions.c sp_execute.c sp_upload_validation.c" |
| 7 | sources="$sources sp_cookie_encryption.c sp_network_utils.c tweetnacl.c" | 7 | sources="$sources sp_cookie_encryption.c sp_network_utils.c tweetnacl.c" |
| 8 | sources="$sources sp_config_keywords.c sp_var_parser.c sp_var_value.c sp_tree.c" | 8 | sources="$sources sp_config_keywords.c sp_var_parser.c sp_var_value.c sp_tree.c" |
| 9 | sources="$sources sp_pcre_compat.c sp_crypt.c sp_session.c sp_sloppy.c" | 9 | sources="$sources sp_pcre_compat.c sp_crypt.c sp_session.c sp_sloppy.c sp_wrapper.c" |
| 10 | 10 | ||
| 11 | PHP_ARG_ENABLE(snuffleupagus, whether to enable snuffleupagus support, | 11 | PHP_ARG_ENABLE(snuffleupagus, whether to enable snuffleupagus support, |
| 12 | [ --enable-snuffleupagus Enable snuffleupagus support]) | 12 | [ --enable-snuffleupagus Enable snuffleupagus support]) |
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h index 96f9dd4..41d9b77 100644 --- a/src/php_snuffleupagus.h +++ b/src/php_snuffleupagus.h | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include "sp_crypt.h" | 44 | #include "sp_crypt.h" |
| 45 | #include "sp_session.h" | 45 | #include "sp_session.h" |
| 46 | #include "sp_sloppy.h" | 46 | #include "sp_sloppy.h" |
| 47 | #include "sp_wrapper.h" | ||
| 47 | 48 | ||
| 48 | extern zend_module_entry snuffleupagus_module_entry; | 49 | extern zend_module_entry snuffleupagus_module_entry; |
| 49 | #define phpext_snuffleupagus_ptr &snuffleupagus_module_entry | 50 | #define phpext_snuffleupagus_ptr &snuffleupagus_module_entry |
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c index ff0c6c3..1a92f11 100644 --- a/src/snuffleupagus.c +++ b/src/snuffleupagus.c | |||
| @@ -95,6 +95,7 @@ PHP_GINIT_FUNCTION(snuffleupagus) { | |||
| 95 | SP_INIT(snuffleupagus_globals->config.config_cookie); | 95 | SP_INIT(snuffleupagus_globals->config.config_cookie); |
| 96 | SP_INIT(snuffleupagus_globals->config.config_session); | 96 | SP_INIT(snuffleupagus_globals->config.config_session); |
| 97 | SP_INIT(snuffleupagus_globals->config.config_eval); | 97 | SP_INIT(snuffleupagus_globals->config.config_eval); |
| 98 | SP_INIT(snuffleupagus_globals->config.config_wrapper); | ||
| 98 | 99 | ||
| 99 | snuffleupagus_globals->config.config_disabled_functions_reg | 100 | snuffleupagus_globals->config.config_disabled_functions_reg |
| 100 | ->disabled_functions = NULL; | 101 | ->disabled_functions = NULL; |
| @@ -103,6 +104,7 @@ PHP_GINIT_FUNCTION(snuffleupagus) { | |||
| 103 | snuffleupagus_globals->config.config_cookie->cookies = NULL; | 104 | snuffleupagus_globals->config.config_cookie->cookies = NULL; |
| 104 | snuffleupagus_globals->config.config_eval->blacklist = NULL; | 105 | snuffleupagus_globals->config.config_eval->blacklist = NULL; |
| 105 | snuffleupagus_globals->config.config_eval->whitelist = NULL; | 106 | snuffleupagus_globals->config.config_eval->whitelist = NULL; |
| 107 | snuffleupagus_globals->config.config_wrapper->whitelist = NULL; | ||
| 106 | 108 | ||
| 107 | #undef SP_INIT | 109 | #undef SP_INIT |
| 108 | #undef SP_INIT_HT | 110 | #undef SP_INIT_HT |
| @@ -160,12 +162,14 @@ PHP_MSHUTDOWN_FUNCTION(snuffleupagus) { | |||
| 160 | sp_list_free(SNUFFLEUPAGUS_G(config).config_cookie->cookies); | 162 | sp_list_free(SNUFFLEUPAGUS_G(config).config_cookie->cookies); |
| 161 | sp_list_free(SNUFFLEUPAGUS_G(config).config_eval->blacklist); | 163 | sp_list_free(SNUFFLEUPAGUS_G(config).config_eval->blacklist); |
| 162 | sp_list_free(SNUFFLEUPAGUS_G(config).config_eval->whitelist); | 164 | sp_list_free(SNUFFLEUPAGUS_G(config).config_eval->whitelist); |
| 165 | sp_list_free(SNUFFLEUPAGUS_G(config).config_wrapper->whitelist); | ||
| 163 | 166 | ||
| 164 | #undef FREE_LST_DISABLE | 167 | #undef FREE_LST_DISABLE |
| 165 | 168 | ||
| 166 | pefree(SNUFFLEUPAGUS_G(config.config_disabled_functions_reg), 1); | 169 | pefree(SNUFFLEUPAGUS_G(config.config_disabled_functions_reg), 1); |
| 167 | pefree(SNUFFLEUPAGUS_G(config.config_disabled_functions_reg_ret), 1); | 170 | pefree(SNUFFLEUPAGUS_G(config.config_disabled_functions_reg_ret), 1); |
| 168 | pefree(SNUFFLEUPAGUS_G(config.config_cookie), 1); | 171 | pefree(SNUFFLEUPAGUS_G(config.config_cookie), 1); |
| 172 | pefree(SNUFFLEUPAGUS_G(config.config_wrapper), 1); | ||
| 169 | 173 | ||
| 170 | UNREGISTER_INI_ENTRIES(); | 174 | UNREGISTER_INI_ENTRIES(); |
| 171 | 175 | ||
| @@ -176,6 +180,14 @@ PHP_RINIT_FUNCTION(snuffleupagus) { | |||
| 176 | #if defined(COMPILE_DL_SNUFFLEUPAGUS) && defined(ZTS) | 180 | #if defined(COMPILE_DL_SNUFFLEUPAGUS) && defined(ZTS) |
| 177 | ZEND_TSRMLS_CACHE_UPDATE(); | 181 | ZEND_TSRMLS_CACHE_UPDATE(); |
| 178 | #endif | 182 | #endif |
| 183 | |||
| 184 | // We need to disable wrappers loaded by extensions loaded after SNUFFLEUPAGUS. | ||
| 185 | if (SNUFFLEUPAGUS_G(config).config_wrapper->enabled && | ||
| 186 | zend_hash_num_elements(php_stream_get_url_stream_wrappers_hash()) != | ||
| 187 | SNUFFLEUPAGUS_G(config).config_wrapper->num_wrapper) { | ||
| 188 | sp_disable_wrapper(); | ||
| 189 | } | ||
| 190 | |||
| 179 | if (NULL != SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key) { | 191 | if (NULL != SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key) { |
| 180 | if (NULL != SNUFFLEUPAGUS_G(config).config_cookie->cookies) { | 192 | if (NULL != SNUFFLEUPAGUS_G(config).config_cookie->cookies) { |
| 181 | zend_hash_apply_with_arguments( | 193 | zend_hash_apply_with_arguments( |
| @@ -243,6 +255,9 @@ static PHP_INI_MH(OnUpdateConfiguration) { | |||
| 243 | if (SNUFFLEUPAGUS_G(config).config_disable_xxe->enable == 0) { | 255 | if (SNUFFLEUPAGUS_G(config).config_disable_xxe->enable == 0) { |
| 244 | hook_libxml_disable_entity_loader(); | 256 | hook_libxml_disable_entity_loader(); |
| 245 | } | 257 | } |
| 258 | if (SNUFFLEUPAGUS_G(config).config_wrapper->enabled) { | ||
| 259 | hook_stream_wrappers(); | ||
| 260 | } | ||
| 246 | hook_disabled_functions(); | 261 | hook_disabled_functions(); |
| 247 | hook_execute(); | 262 | hook_execute(); |
| 248 | 263 | ||
diff --git a/src/sp_config.c b/src/sp_config.c index c652984..e5cb3ce 100644 --- a/src/sp_config.c +++ b/src/sp_config.c | |||
| @@ -23,6 +23,7 @@ sp_config_tokens const sp_func[] = { | |||
| 23 | {.func = parse_eval_whitelist, .token = SP_TOKEN_EVAL_WHITELIST}, | 23 | {.func = parse_eval_whitelist, .token = SP_TOKEN_EVAL_WHITELIST}, |
| 24 | {.func = parse_session, .token = SP_TOKEN_SESSION_ENCRYPTION}, | 24 | {.func = parse_session, .token = SP_TOKEN_SESSION_ENCRYPTION}, |
| 25 | {.func = parse_sloppy_comparison, .token = SP_TOKEN_SLOPPY_COMPARISON}, | 25 | {.func = parse_sloppy_comparison, .token = SP_TOKEN_SLOPPY_COMPARISON}, |
| 26 | {.func = parse_wrapper_whitelist, .token = SP_TOKEN_ALLOW_WRAPPERS}, | ||
| 26 | {NULL, NULL}}; | 27 | {NULL, NULL}}; |
| 27 | 28 | ||
| 28 | /* Top level keyword parsing */ | 29 | /* Top level keyword parsing */ |
| @@ -61,6 +62,26 @@ int parse_empty(char *restrict line, char *restrict keyword, void *retval) { | |||
| 61 | return 0; | 62 | return 0; |
| 62 | } | 63 | } |
| 63 | 64 | ||
| 65 | int parse_list(char *restrict line, char *restrict keyword, void *list_ptr) { | ||
| 66 | zend_string *value = NULL; | ||
| 67 | sp_list_node **list = list_ptr; | ||
| 68 | char *token, *tmp; | ||
| 69 | |||
| 70 | size_t consumed = 0; | ||
| 71 | value = get_param(&consumed, line, SP_TYPE_STR, keyword); | ||
| 72 | if (!value) { | ||
| 73 | return -1; | ||
| 74 | } | ||
| 75 | |||
| 76 | tmp = ZSTR_VAL(value); | ||
| 77 | while ((token = strtok_r(tmp, ",", &tmp))) { | ||
| 78 | *list = sp_list_insert(*list, zend_string_init(token, strlen(token), 1)); | ||
| 79 | } | ||
| 80 | |||
| 81 | pefree(value, 1); | ||
| 82 | return consumed; | ||
| 83 | } | ||
| 84 | |||
| 64 | int parse_php_type(char *restrict line, char *restrict keyword, void *retval) { | 85 | int parse_php_type(char *restrict line, char *restrict keyword, void *retval) { |
| 65 | size_t consumed = 0; | 86 | size_t consumed = 0; |
| 66 | zend_string *value = get_param(&consumed, line, SP_TYPE_STR, keyword); | 87 | zend_string *value = get_param(&consumed, line, SP_TYPE_STR, keyword); |
diff --git a/src/sp_config.h b/src/sp_config.h index d2fa64f..9d58359 100644 --- a/src/sp_config.h +++ b/src/sp_config.h | |||
| @@ -78,6 +78,12 @@ typedef struct { | |||
| 78 | } sp_cookie; | 78 | } sp_cookie; |
| 79 | 79 | ||
| 80 | typedef struct { | 80 | typedef struct { |
| 81 | sp_list_node *whitelist; | ||
| 82 | bool enabled; | ||
| 83 | size_t num_wrapper; // Used to verify if wrappers were added. | ||
| 84 | } sp_config_wrapper; | ||
| 85 | |||
| 86 | typedef struct { | ||
| 81 | bool encrypt; | 87 | bool encrypt; |
| 82 | bool simulation; | 88 | bool simulation; |
| 83 | } sp_config_session; | 89 | } sp_config_session; |
| @@ -166,6 +172,7 @@ typedef struct { | |||
| 166 | sp_config_global_strict *config_global_strict; | 172 | sp_config_global_strict *config_global_strict; |
| 167 | sp_config_disable_xxe *config_disable_xxe; | 173 | sp_config_disable_xxe *config_disable_xxe; |
| 168 | sp_config_eval *config_eval; | 174 | sp_config_eval *config_eval; |
| 175 | sp_config_wrapper *config_wrapper; | ||
| 169 | sp_config_session *config_session; | 176 | sp_config_session *config_session; |
| 170 | bool hook_execute; | 177 | bool hook_execute; |
| 171 | 178 | ||
| @@ -204,6 +211,7 @@ typedef struct { | |||
| 204 | #define SP_TOKEN_EVAL_BLACKLIST ".eval_blacklist" | 211 | #define SP_TOKEN_EVAL_BLACKLIST ".eval_blacklist" |
| 205 | #define SP_TOKEN_EVAL_WHITELIST ".eval_whitelist" | 212 | #define SP_TOKEN_EVAL_WHITELIST ".eval_whitelist" |
| 206 | #define SP_TOKEN_SLOPPY_COMPARISON ".sloppy_comparison" | 213 | #define SP_TOKEN_SLOPPY_COMPARISON ".sloppy_comparison" |
| 214 | #define SP_TOKEN_ALLOW_WRAPPERS ".wrappers_whitelist" | ||
| 207 | 215 | ||
| 208 | // common tokens | 216 | // common tokens |
| 209 | #define SP_TOKEN_ENABLE ".enable(" | 217 | #define SP_TOKEN_ENABLE ".enable(" |
| @@ -256,8 +264,7 @@ typedef struct { | |||
| 256 | // upload_validator | 264 | // upload_validator |
| 257 | #define SP_TOKEN_UPLOAD_SCRIPT ".script(" | 265 | #define SP_TOKEN_UPLOAD_SCRIPT ".script(" |
| 258 | 266 | ||
| 259 | // eval blacklist | 267 | #define SP_TOKEN_LIST ".list(" |
| 260 | #define SP_TOKEN_EVAL_LIST ".list(" | ||
| 261 | 268 | ||
| 262 | int sp_parse_config(const char *); | 269 | int sp_parse_config(const char *); |
| 263 | int parse_array(sp_disabled_function *); | 270 | int parse_array(sp_disabled_function *); |
| @@ -267,6 +274,7 @@ int parse_regexp(char *restrict, char *restrict, void *); | |||
| 267 | int parse_empty(char *restrict, char *restrict, void *); | 274 | int parse_empty(char *restrict, char *restrict, void *); |
| 268 | int parse_cidr(char *restrict, char *restrict, void *); | 275 | int parse_cidr(char *restrict, char *restrict, void *); |
| 269 | int parse_php_type(char *restrict, char *restrict, void *); | 276 | int parse_php_type(char *restrict, char *restrict, void *); |
| 277 | int parse_list(char *restrict, char *restrict, void *); | ||
| 270 | 278 | ||
| 271 | // cleanup | 279 | // cleanup |
| 272 | void sp_disabled_function_list_free(sp_list_node *); | 280 | void sp_disabled_function_list_free(sp_list_node *); |
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c index fb20a43..b86b9d9 100644 --- a/src/sp_config_keywords.c +++ b/src/sp_config_keywords.c | |||
| @@ -166,12 +166,11 @@ int parse_global(char *line) { | |||
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | static int parse_eval_filter_conf(char *line, sp_list_node **list) { | 168 | static int parse_eval_filter_conf(char *line, sp_list_node **list) { |
| 169 | char *token, *tmp; | ||
| 170 | zend_string *rest = NULL; | 169 | zend_string *rest = NULL; |
| 171 | sp_config_eval *eval = SNUFFLEUPAGUS_G(config).config_eval; | 170 | sp_config_eval *eval = SNUFFLEUPAGUS_G(config).config_eval; |
| 172 | 171 | ||
| 173 | sp_config_functions sp_config_funcs[] = { | 172 | sp_config_functions sp_config_funcs[] = { |
| 174 | {parse_str, SP_TOKEN_EVAL_LIST, &rest}, | 173 | {parse_list, SP_TOKEN_LIST, list}, |
| 175 | {parse_empty, SP_TOKEN_SIMULATION, | 174 | {parse_empty, SP_TOKEN_SIMULATION, |
| 176 | &(SNUFFLEUPAGUS_G(config).config_eval->simulation)}, | 175 | &(SNUFFLEUPAGUS_G(config).config_eval->simulation)}, |
| 177 | {parse_str, SP_TOKEN_DUMP, &(SNUFFLEUPAGUS_G(config).config_eval->dump)}, | 176 | {parse_str, SP_TOKEN_DUMP, &(SNUFFLEUPAGUS_G(config).config_eval->dump)}, |
| @@ -184,16 +183,25 @@ static int parse_eval_filter_conf(char *line, sp_list_node **list) { | |||
| 184 | return ret; | 183 | return ret; |
| 185 | } | 184 | } |
| 186 | 185 | ||
| 187 | tmp = ZSTR_VAL(rest); | ||
| 188 | while ((token = strtok_r(tmp, ",", &tmp))) { | ||
| 189 | *list = sp_list_insert(*list, zend_string_init(token, strlen(token), 1)); | ||
| 190 | } | ||
| 191 | if (rest != NULL) { | 186 | if (rest != NULL) { |
| 192 | pefree(rest, 1); | 187 | pefree(rest, 1); |
| 193 | } | 188 | } |
| 194 | return SUCCESS; | 189 | return SUCCESS; |
| 195 | } | 190 | } |
| 196 | 191 | ||
| 192 | int parse_wrapper_whitelist(char *line) { | ||
| 193 | SNUFFLEUPAGUS_G(config).config_wrapper->enabled = true; | ||
| 194 | sp_config_functions sp_config_funcs[] = { | ||
| 195 | {parse_list, SP_TOKEN_LIST, | ||
| 196 | &SNUFFLEUPAGUS_G(config).config_wrapper->whitelist}, | ||
| 197 | {0}}; | ||
| 198 | int ret = parse_keywords(sp_config_funcs, line); | ||
| 199 | if (0 != ret) { | ||
| 200 | return ret; | ||
| 201 | } | ||
| 202 | return SUCCESS; | ||
| 203 | } | ||
| 204 | |||
| 197 | int parse_eval_blacklist(char *line) { | 205 | int parse_eval_blacklist(char *line) { |
| 198 | return parse_eval_filter_conf( | 206 | return parse_eval_filter_conf( |
| 199 | line, &SNUFFLEUPAGUS_G(config).config_eval->blacklist); | 207 | line, &SNUFFLEUPAGUS_G(config).config_eval->blacklist); |
diff --git a/src/sp_config_keywords.h b/src/sp_config_keywords.h index 36c66a5..ab58456 100644 --- a/src/sp_config_keywords.h +++ b/src/sp_config_keywords.h | |||
| @@ -16,5 +16,6 @@ int parse_eval_blacklist(char *line); | |||
| 16 | int parse_eval_whitelist(char *line); | 16 | int parse_eval_whitelist(char *line); |
| 17 | int parse_session(char *line); | 17 | int parse_session(char *line); |
| 18 | int parse_sloppy_comparison(char *line); | 18 | int parse_sloppy_comparison(char *line); |
| 19 | int parse_wrapper_whitelist(char *line); | ||
| 19 | 20 | ||
| 20 | #endif // __SP_CONFIG_KEYWORDS_H | 21 | #endif // __SP_CONFIG_KEYWORDS_H |
diff --git a/src/sp_wrapper.c b/src/sp_wrapper.c new file mode 100644 index 0000000..d9cd296 --- /dev/null +++ b/src/sp_wrapper.c | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | #include "php_snuffleupagus.h" | ||
| 2 | #include "sp_config.h" | ||
| 3 | |||
| 4 | ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus) | ||
| 5 | |||
| 6 | static bool wrapper_is_whitelisted(const zend_string *zs) { | ||
| 7 | const sp_list_node *list = SNUFFLEUPAGUS_G(config).config_wrapper->whitelist; | ||
| 8 | |||
| 9 | if (!zs) { | ||
| 10 | return false; | ||
| 11 | } | ||
| 12 | |||
| 13 | while (list) { | ||
| 14 | if (zend_string_equals_ci(zs, (const zend_string*)list->data)) { | ||
| 15 | return true; | ||
| 16 | } | ||
| 17 | list = list->next; | ||
| 18 | } | ||
| 19 | return false; | ||
| 20 | } | ||
| 21 | |||
| 22 | void sp_disable_wrapper() { | ||
| 23 | HashTable *orig = php_stream_get_url_stream_wrappers_hash(); | ||
| 24 | HashTable *orig_complete = pemalloc(sizeof(*orig_complete), 1); | ||
| 25 | zval *zv; | ||
| 26 | zend_string *zs; | ||
| 27 | |||
| 28 | // Copy the original hashtable into a temporary one, as I'm not sure about | ||
| 29 | // the behaviour of ZEND_HASH_FOREACH when element are removed from the | ||
| 30 | // hashtable used in the loop. | ||
| 31 | zend_hash_init(orig_complete, zend_hash_num_elements(orig), NULL, NULL, 1); | ||
| 32 | zend_hash_copy(orig_complete, orig, NULL); | ||
| 33 | zend_hash_clean(orig); | ||
| 34 | |||
| 35 | ZEND_HASH_FOREACH_STR_KEY_VAL(orig_complete, zs, zv) { | ||
| 36 | if (wrapper_is_whitelisted(zs)) { | ||
| 37 | zend_hash_add(orig, zs, zv); | ||
| 38 | } | ||
| 39 | } | ||
| 40 | ZEND_HASH_FOREACH_END(); | ||
| 41 | |||
| 42 | zend_hash_destroy(orig_complete); | ||
| 43 | pefree(orig_complete, 1); | ||
| 44 | SNUFFLEUPAGUS_G(config).config_wrapper->num_wrapper = zend_hash_num_elements(orig); | ||
| 45 | } | ||
| 46 | |||
| 47 | PHP_FUNCTION(sp_stream_wrapper_register) { | ||
| 48 | void (*orig_handler)(INTERNAL_FUNCTION_PARAMETERS); | ||
| 49 | zend_string *protocol_name = NULL; | ||
| 50 | |||
| 51 | ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_QUIET, 2, EX_NUM_ARGS()); | ||
| 52 | Z_PARAM_STR(protocol_name); | ||
| 53 | ZEND_PARSE_PARAMETERS_END_EX((void)0); | ||
| 54 | |||
| 55 | if (wrapper_is_whitelisted(protocol_name)) { | ||
| 56 | orig_handler = zend_hash_str_find_ptr( | ||
| 57 | SNUFFLEUPAGUS_G(sp_internal_functions_hook), | ||
| 58 | "stream_wrapper_register", sizeof("stream_wrapper_register") - 1); | ||
| 59 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | int hook_stream_wrappers() { | ||
| 64 | TSRMLS_FETCH(); | ||
| 65 | |||
| 66 | HOOK_FUNCTION("stream_wrapper_register", sp_internal_functions_hook, | ||
| 67 | PHP_FN(sp_stream_wrapper_register)); | ||
| 68 | |||
| 69 | return SUCCESS; | ||
| 70 | } | ||
diff --git a/src/sp_wrapper.h b/src/sp_wrapper.h new file mode 100644 index 0000000..f57513a --- /dev/null +++ b/src/sp_wrapper.h | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | #ifndef SP_WRAPPER_H | ||
| 2 | #define SP_WRAPPER_H | ||
| 3 | #include "php_snuffleupagus.h" | ||
| 4 | |||
| 5 | void sp_disable_wrapper(); | ||
| 6 | int hook_stream_wrappers(); | ||
| 7 | |||
| 8 | #endif | ||
diff --git a/src/tests/config/config_stream_wrapper.ini b/src/tests/config/config_stream_wrapper.ini new file mode 100644 index 0000000..0cd7f77 --- /dev/null +++ b/src/tests/config/config_stream_wrapper.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.wrappers_whitelist.list("https,FTP,does_not_exist"); | |||
diff --git a/src/tests/config/config_stream_wrapper_register.ini b/src/tests/config/config_stream_wrapper_register.ini new file mode 100644 index 0000000..ee273a1 --- /dev/null +++ b/src/tests/config/config_stream_wrapper_register.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.wrappers_whitelist.list("php,lelel"); | |||
diff --git a/src/tests/stream_wrapper.phpt b/src/tests/stream_wrapper.phpt new file mode 100644 index 0000000..b4e49a0 --- /dev/null +++ b/src/tests/stream_wrapper.phpt | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | --TEST-- | ||
| 2 | Stream wrapper | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) print "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/config_stream_wrapper.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | file_get_contents('http://qweqwezxc'); | ||
| 10 | file_get_contents('https://qweqwezxc'); | ||
| 11 | file_get_contents('ftp://qweqwezxc'); | ||
| 12 | file_get_contents('lelel://qweqwezxc'); | ||
| 13 | ?> | ||
| 14 | --EXPECTF-- | ||
| 15 | Warning: Unknown: Unable to find the wrapper "php" - did you forget to enable it when you configured PHP? in Unknown on line 0 | ||
| 16 | |||
| 17 | Warning: Unknown: Unable to find the wrapper "php" - did you forget to enable it when you configured PHP? in Unknown on line 0 | ||
| 18 | |||
| 19 | Warning: Unknown: Unable to find the wrapper "php" - did you forget to enable it when you configured PHP? in Unknown on line 0 | ||
| 20 | |||
| 21 | Warning: file_get_contents(): Unable to find the wrapper "http" - did you forget to enable it when you configured PHP? in %a/tests/stream_wrapper.php on line %d | ||
| 22 | |||
| 23 | Warning: file_get_contents(): php_network_getaddresses: getaddrinfo failed: Name or service not known in %a/tests/stream_wrapper.php on line %d | ||
| 24 | |||
| 25 | Warning: file_get_contents(https://qweqwezxc): failed to open stream: php_network_getaddresses: getaddrinfo failed: Name or service not known in %a/tests/stream_wrapper.php on line %d | ||
| 26 | |||
| 27 | Warning: file_get_contents(ftp://qweqwezxc): failed to open stream: operation failed in %a/tests/stream_wrapper.php on line %d | ||
| 28 | |||
| 29 | Warning: file_get_contents(): Unable to find the wrapper "lelel" - did you forget to enable it when you configured PHP? in %a/tests/stream_wrapper.php on line %d | ||
| 30 | |||
| 31 | Warning: file_get_contents(lelel://qweqwezxc): failed to open stream: No such file or directory in %a/tests/stream_wrapper.php on line %d | ||
diff --git a/src/tests/stream_wrapper_register.phpt b/src/tests/stream_wrapper_register.phpt new file mode 100644 index 0000000..31e53ea --- /dev/null +++ b/src/tests/stream_wrapper_register.phpt | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | --TEST-- | ||
| 2 | Stream wrapper | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) print "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/config_stream_wrapper_register.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | class qwe { | ||
| 10 | function stream_open($fname) { | ||
| 11 | return $fname; | ||
| 12 | } | ||
| 13 | } | ||
| 14 | |||
| 15 | stream_wrapper_register("lelel", "qwe"); | ||
| 16 | stream_wrapper_register("lolol", "qwe"); | ||
| 17 | fopen("lelel://asdasd", "r"); | ||
| 18 | fopen("lolol://asdasd", "r"); | ||
| 19 | ?> | ||
| 20 | --EXPECTF-- | ||
| 21 | Warning: fopen(): Unable to find the wrapper "lolol" - did you forget to enable it when you configured PHP? in %a/tests/stream_wrapper_register.php on line %d | ||
| 22 | |||
| 23 | Warning: fopen(): file:// wrapper is disabled in the server configuration in %a/tests/stream_wrapper_register.php on line %d | ||
| 24 | |||
| 25 | Warning: fopen(lolol://asdasd): failed to open stream: no suitable wrapper could be found in %a/tests/stream_wrapper_register.php on line %d | ||
diff --git a/src/tests/stream_wrapper_restore.phpt b/src/tests/stream_wrapper_restore.phpt new file mode 100644 index 0000000..c1bce3b --- /dev/null +++ b/src/tests/stream_wrapper_restore.phpt | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | --TEST-- | ||
| 2 | Stream wrapper | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) print "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/config_stream_wrapper_register.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | stream_wrapper_restore("file"); | ||
| 10 | fopen("file://asdasd", "r"); | ||
| 11 | ?> | ||
| 12 | --EXPECTF-- | ||
| 13 | Notice: stream_wrapper_restore(): file:// was never changed, nothing to restore in %a/tests/stream_wrapper_restore.php on line %d | ||
| 14 | |||
| 15 | Warning: fopen(): Unable to find the wrapper "file" - did you forget to enable it when you configured PHP? in %a/tests/stream_wrapper_restore.php on line %d | ||
| 16 | |||
| 17 | Warning: fopen(file://asdasd): failed to open stream: No such file or directory in %a/tests/stream_wrapper_restore.php on line %d | ||
