summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Fuhrmannek2014-07-15 15:43:14 +0200
committerBen Fuhrmannek2014-07-15 15:43:14 +0200
commit9cb8c448eee428ee1d64323e3e71d4a54a25154a (patch)
tree2b24b6f10c6a879972671d58ee92f206d70e9319
parentbab54996ce99bf66bc3e0e377fecb37e52894dd7 (diff)
replaced suhosin_register_cookie_variable + suhosin_register_cookie_variable_safe
-rw-r--r--suhosin.c179
1 files changed, 6 insertions, 173 deletions
diff --git a/suhosin.c b/suhosin.c
index f57e85a..7fbefc8 100644
--- a/suhosin.c
+++ b/suhosin.c
@@ -28,6 +28,7 @@
28#include "zend_extensions.h" 28#include "zend_extensions.h"
29#include "ext/standard/info.h" 29#include "ext/standard/info.h"
30#include "php_syslog.h" 30#include "php_syslog.h"
31#include "php_variables.h"
31#include "php_suhosin.h" 32#include "php_suhosin.h"
32#include "zend_llist.h" 33#include "zend_llist.h"
33#include "zend_operators.h" 34#include "zend_operators.h"
@@ -618,175 +619,6 @@ static ZEND_INI_MH(OnUpdate_fail)
618 return FAILURE; 619 return FAILURE;
619} 620}
620 621
621/* {{{ proto void suhosin_register_cookie_variable(char *var, zval *val, zval *track_vars_array TSRMLS_DC)
622 Registers a cookie in the RAW cookie array */
623static void suhosin_register_cookie_variable(char *var, zval *val, zval *track_vars_array TSRMLS_DC)
624{
625 char *p = NULL;
626 char *ip; /* index pointer */
627 char *index, *escaped_index = NULL;
628 int var_len, index_len;
629 zval *gpc_element, **gpc_element_p;
630 zend_bool is_array = 0;
631 HashTable *symtable1 = NULL;
632
633 assert(var != NULL);
634
635 symtable1 = Z_ARRVAL_P(track_vars_array);
636
637 /*
638 * Prepare variable name
639 */
640
641 /* ignore leading spaces in the variable name */
642 while (*var && *var==' ') {
643 var++;
644 }
645
646 /* ensure that we don't have spaces or dots in the variable name (not binary safe) */
647 for (p = var; *p; p++) {
648 if (*p == ' ' || *p == '.') {
649 *p='_';
650 } else if (*p == '[') {
651 is_array = 1;
652 ip = p;
653 *p = 0;
654 break;
655 }
656 }
657 var_len = p - var;
658
659 if (var_len==0) { /* empty variable name, or variable name with a space in it */
660 zval_dtor(val);
661 return;
662 }
663
664 index = var;
665 index_len = var_len;
666
667 if (is_array) {
668 while (1) {
669 char *index_s;
670 int new_idx_len = 0;
671
672 ip++;
673 index_s = ip;
674 if (isspace(*ip)) {
675 ip++;
676 }
677 if (*ip==']') {
678 index_s = NULL;
679 } else {
680 ip = strchr(ip, ']');
681 if (!ip) {
682 /* PHP variables cannot contain '[' in their names, so we replace the character with a '_' */
683 *(index_s - 1) = '_';
684
685 index_len = var_len = 0;
686 if (index) {
687 index_len = var_len = strlen(index);
688 }
689 goto plain_var;
690 return;
691 }
692 *ip = 0;
693 new_idx_len = strlen(index_s);
694 }
695
696 if (!index) {
697 MAKE_STD_ZVAL(gpc_element);
698 array_init(gpc_element);
699 zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
700 } else {
701#if PHP_VERSION_ID < 50400
702 if (PG(magic_quotes_gpc) && (index != var)) {
703 /* no need to addslashes() the index if it's the main variable name */
704 escaped_index = php_addslashes(index, index_len, &index_len, 0 TSRMLS_CC);
705 } else {
706#endif
707 escaped_index = index;
708#if PHP_VERSION_ID < 50400
709 }
710#endif
711 if (zend_symtable_find(symtable1, escaped_index, index_len + 1, (void **) &gpc_element_p) == FAILURE
712 || Z_TYPE_PP(gpc_element_p) != IS_ARRAY) {
713 MAKE_STD_ZVAL(gpc_element);
714 array_init(gpc_element);
715 zend_symtable_update(symtable1, escaped_index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
716 }
717 if (index != escaped_index) {
718 efree(escaped_index);
719 }
720 }
721 symtable1 = Z_ARRVAL_PP(gpc_element_p);
722 /* ip pointed to the '[' character, now obtain the key */
723 index = index_s;
724 index_len = new_idx_len;
725
726 ip++;
727 if (*ip == '[') {
728 is_array = 1;
729 *ip = 0;
730 } else {
731 goto plain_var;
732 }
733 }
734 } else {
735plain_var:
736 MAKE_STD_ZVAL(gpc_element);
737 gpc_element->value = val->value;
738 Z_TYPE_P(gpc_element) = Z_TYPE_P(val);
739 if (!index) {
740 zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
741 } else {
742#if PHP_VERSION_ID < 50400
743 if (PG(magic_quotes_gpc)) {
744 escaped_index = php_addslashes(index, index_len, &index_len, 0 TSRMLS_CC);
745 } else {
746#endif
747 escaped_index = index;
748#if PHP_VERSION_ID < 50400
749 }
750#endif
751 /*
752 * According to rfc2965, more specific paths are listed above the less specific ones.
753 * If we encounter a duplicate cookie name, we should skip it, since it is not possible
754 * to have the same (plain text) cookie name for the same path and we should not overwrite
755 * more specific cookies with the less specific ones.
756 */
757 if (zend_symtable_exists(symtable1, escaped_index, index_len + 1)) {
758 zval_ptr_dtor(&gpc_element);
759 } else {
760 zend_symtable_update(symtable1, escaped_index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
761 }
762 if (escaped_index != index) {
763 efree(escaped_index);
764 }
765 }
766 }
767}
768/* }}} */
769
770static void suhosin_register_cookie_variable_safe(char *var, char *strval, int str_len, zval *track_vars_array TSRMLS_DC)
771{
772 zval new_entry;
773 assert(strval != NULL);
774
775 /* Prepare value */
776 Z_STRLEN(new_entry) = str_len;
777#if PHP_VERSION_ID < 50400
778 if (PG(magic_quotes_gpc)) {
779 Z_STRVAL(new_entry) = php_addslashes(strval, Z_STRLEN(new_entry), &Z_STRLEN(new_entry), 0 TSRMLS_CC);
780 } else {
781#endif
782 Z_STRVAL(new_entry) = estrndup(strval, Z_STRLEN(new_entry));
783#if PHP_VERSION_ID < 50400
784 }
785#endif
786 Z_TYPE(new_entry) = IS_STRING;
787
788 suhosin_register_cookie_variable(var, &new_entry, track_vars_array TSRMLS_CC);
789}
790 622
791 623
792/* {{{ proto string suhosin_encrypt_cookie(string name, string value) 624/* {{{ proto string suhosin_encrypt_cookie(string name, string value)
@@ -833,7 +665,7 @@ static PHP_FUNCTION(suhosin_get_raw_cookies)
833 int val_len; 665 int val_len;
834 666
835 array_init(array_ptr); 667 array_init(array_ptr);
836 668 SDEBUG("get_raw_cookies %s", SUHOSIN_G(raw_cookie));
837 if (SUHOSIN_G(raw_cookie)) { 669 if (SUHOSIN_G(raw_cookie)) {
838 res = estrdup(SUHOSIN_G(raw_cookie)); 670 res = estrdup(SUHOSIN_G(raw_cookie));
839 } else { 671 } else {
@@ -843,17 +675,18 @@ static PHP_FUNCTION(suhosin_get_raw_cookies)
843 var = php_strtok_r(res, ";", &strtok_buf); 675 var = php_strtok_r(res, ";", &strtok_buf);
844 676
845 while (var) { 677 while (var) {
678 SDEBUG("raw cookie: %s", var);
846 val = strchr(var, '='); 679 val = strchr(var, '=');
847 if (val) { /* have a value */ 680 if (val) { /* have a value */
848 *val++ = '\0'; 681 *val++ = '\0';
849 php_url_decode(var, strlen(var)); 682 php_url_decode(var, strlen(var));
850 val_len = php_url_decode(val, strlen(val)); 683 val_len = php_url_decode(val, strlen(val));
851 suhosin_register_cookie_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); 684 php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
852 } else { 685 } else {
853 php_url_decode(var, strlen(var)); 686 php_url_decode(var, strlen(var));
854 val_len = 0; 687 val_len = 0;
855 val = ""; 688 val = "";
856 suhosin_register_cookie_variable_safe(var, "", 0, array_ptr TSRMLS_CC); 689 php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
857 } 690 }
858 var = php_strtok_r(NULL, ";", &strtok_buf); 691 var = php_strtok_r(NULL, ";", &strtok_buf);
859 } 692 }
@@ -1049,7 +882,7 @@ char *suhosin_getenv(char *name, size_t name_len TSRMLS_DC)
1049 tmp = getenv(name); 882 tmp = getenv(name);
1050 efree(name); 883 efree(name);
1051 if (tmp) { 884 if (tmp) {
1052 return(estrdup(tmp)); 885 return estrdup(tmp);
1053 } 886 }
1054 } 887 }
1055 return NULL; 888 return NULL;