Strict Session管理パッチ(4.4.8用)
以前、Strict Session管理パッチ(4.4.2用)を作成した事をコレを見て思い出しました。。。作業怠慢でゴメンナサイ。
PHP本体に付属しているセッション管理の拡張モジュールは使わない方針とはいえ、自分で使ってないのがバレバレです。(w
同期を図るべく、4.4.8用のStrict Session管理パッチを作成。
大垣さんのサイトから直接DLできるように後で連絡しよっと。。。って、もうじき4.4.9がリリースされそうな雰囲気なので、このパッチは短命な気がしますねぇ。うーん。とりあえず公開。
このパッチがPHP4最後(EoL)への餞となるか。。。って、ならないような気がします。しかもプンプン。(w
--- php-4.4.8,orig/ext/session/mod_files.c 2007-12-31 16:22:51.000000000 +0900 +++ php-4.4.8/ext/session/mod_files.c 2008-07-14 15:56:01.000000000 +0900 @@ -405,6 +405,35 @@ return SUCCESS; } +PS_VALIDATE_SID_FUNC(files) +{ + char buf[MAXPATHLEN]; + int fd; + PS_FILES_DATA; + + if (!ps_files_valid_key(key)) { + return FAILURE; + } + + if (!PS(use_strict_mode)) { + return SUCCESS; + } + + if (!ps_files_path_create(buf, sizeof(buf), data, key)) { + return FAILURE; + } + + fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, + 0600); + + if (fd != -1) { + close(fd); + return SUCCESS; + } + + return FAILURE; +} + /* * Local variables: * tab-width: 4 --- php-4.4.8,orig/ext/session/mod_mm.c 2007-12-31 16:22:51.000000000 +0900 +++ php-4.4.8/ext/session/mod_mm.c 2008-07-14 15:56:01.000000000 +0900 @@ -425,6 +425,42 @@ return SUCCESS; } +PS_VALIDATE_SID_FUNC(mm) +{ + PS_MM_DATA; + ps_sd *sd; + const char *p; + char c; + int ret = SUCCESS; + + for (p = key; (c = *p); p++) { + /* valid characters are a..z,A..Z,0..9 */ + if (!((c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') + || c == ',' + || c == '-')) { + return FAILURE; + } + } + + if (!PS(use_strict_mode)) { + return SUCCESS; + } + + mm_lock(data->mm, MM_LOCK_RD); + + sd = ps_sd_lookup(data, key, 0); + if (sd) { + mm_unlock(data->mm); + return SUCCESS; + } + + mm_unlock(data->mm); + + return FAILURE; +} + #endif /* --- php-4.4.8,orig/ext/session/mod_user.c 2007-12-31 16:22:51.000000000 +0900 +++ php-4.4.8/ext/session/mod_user.c 2008-07-14 15:56:01.000000000 +0900 @@ -23,7 +23,7 @@ #include "mod_user.h" ps_module ps_mod_user = { - PS_MOD(user) + PS_MOD_SID(user) }; #define SESS_ZVAL_LONG(val, a) \ @@ -174,6 +174,83 @@ FINISH; } +PS_CREATE_SID_FUNC(user) +{ + int i; + char *val = NULL; + zval *retval; + ps_user *mdata = PS_GET_MOD_DATA(); + + if (!mdata) + return estrndup("", 0); + + if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { + return php_session_create_id(mod_data, newlen TSRMLS_CC); + } + retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); + + if (retval) { + if (Z_TYPE_P(retval) == IS_STRING) { + val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); + } else { + val = estrndup("", 0); + } + zval_ptr_dtor(&retval); + } else { + val = estrndup("", 0); + } + + return val; +} + +static int ps_user_valid_key(const char *key TSRMLS_DC) +{ + size_t len; + const char *p; + char c; + int ret = SUCCESS; + + for (p = key; (c = *p); p++) { + /* valid characters are a..z,A..Z,0..9 */ + if (!((c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') + || c == ',' + || c == '-')) { + ret = FAILURE; + break; + } + } + + len = p - key; + + if (len == 0) + ret = FAILURE; + + return ret; +} + +PS_VALIDATE_SID_FUNC(user) +{ + zval *args[1]; + STDVARS; + + if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { + return ps_user_valid_key(key TSRMLS_CC); + } + SESS_ZVAL_STRING(key, args[0]); + + retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); + + if (retval) { + convert_to_long(retval); + ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; + zval_ptr_dtor(&retval); + } + + return ret; +} + /* * Local variables: * tab-width: 4 --- php-4.4.8,orig/ext/session/mod_user.h 2007-12-31 16:22:51.000000000 +0900 +++ php-4.4.8/ext/session/mod_user.h 2008-07-14 15:56:01.000000000 +0900 @@ -22,7 +22,7 @@ #define MOD_USER_H typedef union { - zval *names[6]; + zval *names[8]; struct { zval *ps_open; zval *ps_close; @@ -30,6 +30,8 @@ zval *ps_write; zval *ps_destroy; zval *ps_gc; + zval *ps_create; + zval *ps_validate; } name; } ps_user; --- php-4.4.8,orig/ext/session/php_session.h 2007-12-31 16:22:51.000000000 +0900 +++ php-4.4.8/ext/session/php_session.h 2008-07-14 15:56:02.000000000 +0900 @@ -23,7 +23,7 @@ #include "ext/standard/php_var.h" -#define PHP_SESSION_API 20020330 +#define PHP_SESSION_API 20051121 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC @@ -32,6 +32,7 @@ #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC +#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC /* default create id function */ char *php_session_create_id(PS_CREATE_SID_ARGS); @@ -45,6 +46,7 @@ int (*s_destroy)(PS_DESTROY_ARGS); int (*s_gc)(PS_GC_ARGS); char *(*s_create_sid)(PS_CREATE_SID_ARGS); + int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); } ps_module; #define PS_GET_MOD_DATA() *mod_data @@ -57,6 +59,7 @@ #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) +#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) #define PS_FUNCS(x) \ PS_OPEN_FUNC(x); \ @@ -65,11 +68,12 @@ PS_WRITE_FUNC(x); \ PS_DESTROY_FUNC(x); \ PS_GC_FUNC(x); \ - PS_CREATE_SID_FUNC(x) + PS_CREATE_SID_FUNC(x); \ + PS_VALIDATE_SID_FUNC(x) #define PS_MOD(x) \ #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ - ps_delete_##x, ps_gc_##x, php_session_create_id + ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x /* SID enabled module handler definitions */ #define PS_FUNCS_SID(x) \ @@ -79,11 +83,12 @@ PS_WRITE_FUNC(x); \ PS_DESTROY_FUNC(x); \ PS_GC_FUNC(x); \ - PS_CREATE_SID_FUNC(x) + PS_CREATE_SID_FUNC(x); \ + PS_VALIDATE_SID(x) #define PS_MOD_SID(x) \ #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ - ps_delete_##x, ps_gc_##x, ps_create_sid_##x + ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x typedef enum { php_session_disabled, @@ -119,6 +124,7 @@ zend_bool use_cookies; zend_bool use_only_cookies; zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ + zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ int send_cookie; int define_sid; --- php-4.4.8,orig/ext/session/session.c 2007-12-31 16:22:51.000000000 +0900 +++ php-4.4.8/ext/session/session.c 2008-07-14 15:56:01.000000000 +0900 @@ -160,6 +160,7 @@ STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals) @@ -683,6 +684,16 @@ return; } + + /* If there is an ID, use session module to verify it */ + if (PS(id)) { + if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { + efree(PS(id)); + PS(id) = NULL; + PS(send_cookie) = 1; + } + } + /* If there is no ID, use session module to create one */ if (!PS(id)) PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); @@ -1312,22 +1323,29 @@ } /* }}} */ -/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) +/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) Sets user-level functions */ PHP_FUNCTION(session_set_save_handler) { - zval **args[6]; - int i; + zval **args[8]; + int i, numargs; ps_user *mdata; char *name; - if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) + numargs = ZEND_NUM_ARGS(); + args[6] = NULL; + args[7] = NULL; + + if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) WRONG_PARAM_COUNT; if (PS(session_status) != php_session_none) RETURN_FALSE; - for (i = 0; i < 6; i++) { + for (i = 0; i < 8; i++) { + if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { + continue; + } if (!zend_is_callable(*args[i], 0, &name)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); efree(name); @@ -1340,7 +1358,11 @@ mdata = emalloc(sizeof(*mdata)); - for (i = 0; i < 6; i++) { + for (i = 0; i < 8; i++) { + if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { + mdata->names[i] = NULL; + continue; + } ZVAL_ADDREF(*args[i]); mdata->names[i] = *args[i]; }