@@ -116,6 +116,9 @@ static inline void php_rinit_session_globals(void) /* {{{ */
116
116
PS (define_sid ) = 1 ;
117
117
PS (session_vars ) = NULL ;
118
118
PS (module_number ) = my_module_number ;
119
+ #if defined(HAVE_OPENSSL_EXT )
120
+ PS (ssl_iv ) = NULL ;
121
+ #endif
119
122
ZVAL_UNDEF (& PS (http_session_vars ));
120
123
}
121
124
/* }}} */
@@ -143,6 +146,13 @@ static inline void php_rshutdown_session_globals(void) /* {{{ */
143
146
PS (session_vars ) = NULL ;
144
147
}
145
148
149
+ #if defined(HAVE_OPENSSL_EXT )
150
+ if (PS (ssl_iv )) {
151
+ zend_string_release_ex (PS (ssl_iv ), 0 );
152
+ PS (ssl_iv ) = NULL ;
153
+ }
154
+ #endif
155
+
146
156
/* User save handlers may end up directly here by misuse, bugs in user script, etc. */
147
157
/* Set session status to prevent error while restoring save handler INI value. */
148
158
PS (session_status ) = php_session_none ;
@@ -462,6 +472,41 @@ static int php_session_initialize(void) /* {{{ */
462
472
php_session_decode (val );
463
473
zend_string_release_ex (val , 0 );
464
474
}
475
+ #if defined(HAVE_OPENSSL_EXT )
476
+ if (PS (ssl_encrypt )) {
477
+ zend_long ssl_method_len = strlen (PS (ssl_method ));
478
+ if (!ssl_method_len ) {
479
+ php_error_docref (NULL , E_WARNING , "A cipher method is needed to encrypt the session" );
480
+ PS (ssl_encrypt ) = 0 ;
481
+ } else {
482
+ zend_string * iv ;
483
+ zend_long iv_len ;
484
+ zend_long ssl_tag_len = strlen (PS (ssl_tag ));
485
+
486
+ if (PS (ssl_iv ))
487
+ zend_string_release_ex (PS (ssl_iv ), 0 );
488
+
489
+ if ((iv_len = php_openssl_cipher_iv_length (PS (ssl_method ))) == -1 || iv_len == 0 ) {
490
+ php_error_docref (NULL , E_ERROR , "session.ssl_method `%s` is invalid" , PS (ssl_method ));
491
+ return FAILURE ;
492
+ }
493
+
494
+ if ((iv = php_openssl_random_pseudo_bytes (iv_len )) == NULL ) {
495
+ php_error_docref (NULL , E_ERROR , "session iv data failure" );
496
+ return FAILURE ;
497
+ }
498
+
499
+ if (!ssl_tag_len )
500
+ PS (ssl_tag ) = NULL ;
501
+ PS (ssl_tag_len ) = ssl_tag_len ;
502
+
503
+ ZSTR_VAL (iv )[iv_len ] = 0 ;
504
+ PS (ssl_method_len ) = ssl_method_len ;
505
+ PS (ssl_iv ) = iv ;
506
+ PS (ssl_iv_len ) = iv_len ;
507
+ }
508
+ }
509
+ #endif
465
510
return SUCCESS ;
466
511
}
467
512
/* }}} */
@@ -823,6 +868,13 @@ PHP_INI_BEGIN()
823
868
PHP_INI_ENTRY ("session.sid_length" , "32" , PHP_INI_ALL , OnUpdateSidLength )
824
869
PHP_INI_ENTRY ("session.sid_bits_per_character" , "4" , PHP_INI_ALL , OnUpdateSidBits )
825
870
STD_PHP_INI_BOOLEAN ("session.lazy_write" , "1" , PHP_INI_ALL , OnUpdateLazyWrite , lazy_write , php_ps_globals , ps_globals )
871
+ #if defined(HAVE_OPENSSL_EXT )
872
+ STD_PHP_INI_BOOLEAN ("session.ssl_encrypt" , "0" , PHP_INI_ALL , OnUpdateBool , ssl_encrypt , php_ps_globals , ps_globals )
873
+ STD_PHP_INI_ENTRY ("session.ssl_method" , "" , PHP_INI_ALL , OnUpdateSessionString , ssl_method , php_ps_globals , ps_globals )
874
+ STD_PHP_INI_ENTRY ("session.ssl_tag" , "" , PHP_INI_ALL , OnUpdateSessionString , ssl_tag , php_ps_globals , ps_globals )
875
+ #endif
876
+
877
+ /* Commented out until future discussion */
826
878
827
879
/* Upload progress */
828
880
STD_PHP_INI_BOOLEAN ("session.upload_progress.enabled" ,
@@ -836,15 +888,69 @@ PHP_INI_BEGIN()
836
888
STD_PHP_INI_ENTRY ("session.upload_progress.freq" , "1%" , ZEND_INI_PERDIR , OnUpdateRfc1867Freq , rfc1867_freq , php_ps_globals , ps_globals )
837
889
STD_PHP_INI_ENTRY ("session.upload_progress.min_freq" ,
838
890
"1" , ZEND_INI_PERDIR , OnUpdateReal , rfc1867_min_freq ,php_ps_globals , ps_globals )
839
-
840
- /* Commented out until future discussion */
841
891
/* PHP_INI_ENTRY("session.encode_sources", "globals,track", PHP_INI_ALL, NULL) */
842
892
PHP_INI_END ()
843
- /* }}} */
893
+ /* }}} */
844
894
845
895
/* ***************
846
896
* Serializers *
847
897
*************** */
898
+
899
+ #if defined(HAVE_OPENSSL_EXT )
900
+ static int php_session_encrypt (smart_str * buf ) /* {{{ */
901
+ {
902
+ zend_string * buffer ;
903
+ smart_str res = {0 };
904
+
905
+ if (!PS (ssl_encrypt ) || !PS (id ) || !buf -> a )
906
+ return SUCCESS ;
907
+
908
+ zval * ztag = NULL ;
909
+
910
+ if (PS (ssl_tag_len ) > 0 ) {
911
+ ztag = emalloc (sizeof (* ztag ));
912
+ ZVAL_STRINGL (ztag , PS (ssl_tag ), PS (ssl_tag_len ));
913
+ }
914
+
915
+ if ((buffer = php_openssl_encrypt (ZSTR_VAL (buf -> s ), buf -> a , PS (ssl_method ), PS (ssl_method_len ),
916
+ ZSTR_VAL (PS (id )), ZSTR_LEN (PS (id )), 0 , ZSTR_VAL (PS (ssl_iv )), PS (ssl_iv_len ),
917
+ ztag , PS (ssl_tag_len ), NULL , 0 )) == NULL ) {
918
+ php_error_docref (NULL , E_WARNING , "Cannot encrypt the session data with method '%s', tag '%s'" ,
919
+ PS (ssl_method ), PS (ssl_tag ));
920
+ efree (ztag );
921
+ return FAILURE ;
922
+ }
923
+
924
+ smart_str_free (buf );
925
+ res .s = zend_string_dup (buffer , 0 );
926
+ res .a = ZSTR_LEN (buffer );
927
+ * buf = res ;
928
+ zend_string_release_ex (buffer , 0 );
929
+ efree (ztag );
930
+ return SUCCESS ;
931
+ }
932
+ /* }}} */
933
+
934
+ static zend_string * php_session_decrypt (PS_SERIALIZER_DECODE_ARGS ) /* {{{ */
935
+ {
936
+ zend_string * buffer ;
937
+
938
+ if (!PS (ssl_encrypt ) || !PS (id ) || !vallen )
939
+ return NULL ;
940
+
941
+ if ((buffer = php_openssl_decrypt ((char * )val , vallen , PS (ssl_method ), PS (ssl_method_len ),
942
+ ZSTR_VAL (PS (id )), ZSTR_LEN (PS (id )), 0 , ZSTR_VAL (PS (ssl_iv )), PS (ssl_iv_len ),
943
+ PS (ssl_tag ), PS (ssl_tag_len ), NULL , 0 )) == NULL ) {
944
+ php_error_docref (NULL , E_WARNING , "Cannot decrypt the session data with method '%s'" ,
945
+ PS (ssl_method ));
946
+ return NULL ;
947
+ }
948
+
949
+ return buffer ;
950
+ }
951
+ /* }}} */
952
+ #endif
953
+
848
954
PS_SERIALIZER_ENCODE_FUNC (php_serialize ) /* {{{ */
849
955
{
850
956
smart_str buf = {0 };
@@ -853,6 +959,9 @@ PS_SERIALIZER_ENCODE_FUNC(php_serialize) /* {{{ */
853
959
IF_SESSION_VARS () {
854
960
PHP_VAR_SERIALIZE_INIT (var_hash );
855
961
php_var_serialize (& buf , Z_REFVAL (PS (http_session_vars )), & var_hash );
962
+ #if defined(HAVE_OPENSSL_EXT )
963
+ php_session_encrypt (& buf );
964
+ #endif
856
965
PHP_VAR_SERIALIZE_DESTROY (var_hash );
857
966
}
858
967
return buf .s ;
@@ -867,6 +976,13 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */
867
976
int result ;
868
977
zend_string * var_name = zend_string_init ("_SESSION" , sizeof ("_SESSION" ) - 1 , 0 );
869
978
979
+ #if defined(HAVE_OPENSSL_EXT )
980
+ zend_string * buffer = php_session_decrypt (val , vallen );
981
+ if (buffer ) {
982
+ val = ZSTR_VAL (buffer );
983
+ endptr = val + ZSTR_LEN (buffer );
984
+ }
985
+ #endif
870
986
ZVAL_NULL (& session_vars );
871
987
PHP_VAR_UNSERIALIZE_INIT (var_hash );
872
988
result = php_var_unserialize (
@@ -887,9 +1003,14 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */
887
1003
Z_ADDREF_P (& PS (http_session_vars ));
888
1004
zend_hash_update_ind (& EG (symbol_table ), var_name , & PS (http_session_vars ));
889
1005
zend_string_release_ex (var_name , 0 );
1006
+ #if defined(HAVE_OPENSSL_EXT )
1007
+ if (buffer )
1008
+ zend_string_release_ex (buffer , 0 );
1009
+ #endif
1010
+
890
1011
return result || !vallen ? SUCCESS : FAILURE ;
891
1012
}
892
- /* }}} */
1013
+ /* }}} */
893
1014
894
1015
#define PS_BIN_NR_OF_BITS 8
895
1016
#define PS_BIN_UNDEF (1<<(PS_BIN_NR_OF_BITS-1))
@@ -911,6 +1032,9 @@ PS_SERIALIZER_ENCODE_FUNC(php_binary) /* {{{ */
911
1032
);
912
1033
913
1034
smart_str_0 (& buf );
1035
+ #if defined(HAVE_OPENSSL_EXT )
1036
+ php_session_encrypt (& buf );
1037
+ #endif
914
1038
PHP_VAR_SERIALIZE_DESTROY (var_hash );
915
1039
916
1040
return buf .s ;
@@ -925,6 +1049,13 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
925
1049
zend_string * name ;
926
1050
php_unserialize_data_t var_hash ;
927
1051
zval * current , rv ;
1052
+ #if defined(HAVE_OPENSSL_EXT )
1053
+ zend_string * buffer = php_session_decrypt (val , vallen );
1054
+ if (buffer ) {
1055
+ val = ZSTR_VAL (buffer );
1056
+ endptr = val + ZSTR_LEN (buffer );
1057
+ }
1058
+ #endif
928
1059
929
1060
PHP_VAR_UNSERIALIZE_INIT (var_hash );
930
1061
@@ -954,6 +1085,10 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
954
1085
955
1086
php_session_normalize_vars ();
956
1087
PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
1088
+ #if defined(HAVE_OPENSSL_EXT )
1089
+ if (buffer )
1090
+ zend_string_release_ex (buffer , 0 );
1091
+ #endif
957
1092
958
1093
return SUCCESS ;
959
1094
}
@@ -981,6 +1116,9 @@ PS_SERIALIZER_ENCODE_FUNC(php) /* {{{ */
981
1116
);
982
1117
983
1118
smart_str_0 (& buf );
1119
+ #if defined(HAVE_OPENSSL_EXT )
1120
+ php_session_encrypt (& buf );
1121
+ #endif
984
1122
985
1123
PHP_VAR_SERIALIZE_DESTROY (var_hash );
986
1124
return buf .s ;
@@ -997,6 +1135,13 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
997
1135
php_unserialize_data_t var_hash ;
998
1136
zval * current , rv ;
999
1137
1138
+ #if defined(HAVE_OPENSSL_EXT )
1139
+ zend_string * buffer = php_session_decrypt (val , vallen );
1140
+ if (buffer ) {
1141
+ val = ZSTR_VAL (buffer );
1142
+ endptr = val + ZSTR_LEN (buffer );
1143
+ }
1144
+ #endif
1000
1145
PHP_VAR_UNSERIALIZE_INIT (var_hash );
1001
1146
1002
1147
p = val ;
@@ -1031,6 +1176,10 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
1031
1176
php_session_normalize_vars ();
1032
1177
1033
1178
PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
1179
+ #if defined(HAVE_OPENSSL_EXT )
1180
+ if (buffer )
1181
+ zend_string_release_ex (buffer , 0 );
1182
+ #endif
1034
1183
1035
1184
return retval ;
1036
1185
}
0 commit comments