diff options
| author | Ben Fuhrmannek | 2014-07-15 15:43:14 +0200 |
|---|---|---|
| committer | Ben Fuhrmannek | 2014-07-15 15:43:14 +0200 |
| commit | 9cb8c448eee428ee1d64323e3e71d4a54a25154a (patch) | |
| tree | 2b24b6f10c6a879972671d58ee92f206d70e9319 /suhosin.c | |
| parent | bab54996ce99bf66bc3e0e377fecb37e52894dd7 (diff) | |
replaced suhosin_register_cookie_variable + suhosin_register_cookie_variable_safe
Diffstat (limited to 'suhosin.c')
| -rw-r--r-- | suhosin.c | 179 |
1 files changed, 6 insertions, 173 deletions
| @@ -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 */ | ||
| 623 | static 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 { | ||
| 735 | plain_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 | |||
| 770 | static 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; |
