[PHP-users 28314] Re: Strict Sessionパッチ
Seiji Masugata
s.masugata @ digicom.dnp.co.jp
2006年 2月 3日 (金) 12:47:48 JST
こんにちわ、桝形です。
> 昨年の11月にHardedned PHPのStefanさんがStrict Sessionパッチを公開さ
> れました。PHP 5.1.2にもそのまま適用できるのですが、SQLite用のvalidation
> 関数が定義されていない為、SQLiteと一緒にビルドできませんでした。
>
> 個人的なニーズがあったのでSQLiteも一緒にビルドできるパッチを作りました。
>
> http://blog.ohgaki.net/index.php/yohgaki/2006/02/02/strict_sessioncric_a_a_a
>
> PHP4は運用していないのでパッチは作っていません。PHP 5.1.2用のみです。
オリジナルのStrict SessionパッチがPHP4.4.2では当たらないようなので
手直ししてみました。
(mm辺りとか)検証していないので人柱になってくれる方がいたら嬉しいです。
fileとユーザー定義のハンドラ辺りでの検証はやってますけど。
既に似たようなモノがあったらスミマセン。
少し長くて恐縮ですが。。。
------------------------------------------------------------------------------
--- php-4.4.2,orig/ext/session/mod_files.c 2006-01-01 22:46:56.000000000 +0900
+++ php-4.4.2/ext/session/mod_files.c 2006-02-02 18:09:37.000000000 +0900
@@ -389,6 +389,34 @@
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.2,orig/ext/session/mod_mm.c 2006-01-01 22:46:56.000000000 +0900
+++ php-4.4.2/ext/session/mod_mm.c 2006-02-02 18:09:37.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.2,orig/ext/session/mod_user.c 2006-01-01 22:46:56.000000000 +0900
+++ php-4.4.2/ext/session/mod_user.c 2006-02-02 18:09:37.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.2,orig/ext/session/mod_user.h 2006-01-01 22:46:56.000000000 +0900
+++ php-4.4.2/ext/session/mod_user.h 2006-02-02 18:09:37.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.2,orig/ext/session/php_session.h 2006-01-01 22:46:56.000000000 +0900
+++ php-4.4.2/ext/session/php_session.h 2006-02-02 18:09:37.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,
@@ -120,6 +125,7 @@
zend_bool use_only_cookies;
zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
int send_cookie;
int define_sid;
} php_ps_globals;
--- php-4.4.2,orig/ext/session/session.c 2006-01-01 22:46:56.000000000 +0900
+++ php-4.4.2/ext/session/session.c 2006-02-02 18:09:37.000000000 +0900
@@ -155,6 +155,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)
@@ -637,6 +638,15 @@
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);
@@ -1256,22 +1266,29 @@
}
/* }}} */
-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
- Sets user-level functions */
+/* {{{ 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);
@@ -1284,7 +1301,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];
}
------------------------------------------------------------------------------
--
Seiji Masugata <s.masugata @ digicom.dnp.co.jp>
PHP-users メーリングリストの案内