diff options
Diffstat (limited to 'ext/session/mod_files.c')
-rw-r--r-- | ext/session/mod_files.c | 81 |
1 files changed, 47 insertions, 34 deletions
diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 053c617dec..e9dc25a4b8 100644 --- a/ext/session/mod_files.c +++ b/ext/session/mod_files.c @@ -61,40 +61,9 @@ typedef struct { } ps_files; ps_module ps_mod_files = { - PS_MOD(files) + PS_MOD_SID(files) }; -/* If you change the logic here, please also update the error message in - * ps_files_open() appropriately */ -static int ps_files_valid_key(const char *key) -{ - size_t len; - const char *p; - char c; - int ret = 1; - - 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 = 0; - break; - } - } - - len = p - key; - - /* Somewhat arbitrary length limit here, but should be way more than - anyone needs and avoids file-level warnings later on if we exceed MAX_PATH */ - if (len == 0 || len > 128) { - ret = 0; - } - - return ret; -} static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, const char *key) { @@ -155,11 +124,11 @@ static void ps_files_open(ps_files *data, const char *key TSRMLS_DC) ps_files_close(data); - if (!ps_files_valid_key(key)) { + if (php_session_valid_key(key) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'"); - PS(invalid_session_id) = 1; return; } + if (!ps_files_path_create(buf, sizeof(buf), data, key)) { return; } @@ -253,6 +222,21 @@ static int ps_files_cleanup_dir(const char *dirname, int maxlifetime TSRMLS_DC) return (nrdels); } +static int ps_files_key_exists(ps_files *data, const char *key TSRMLS_DC) +{ + char buf[MAXPATHLEN]; + struct stat sbuf; + + if (!key || !ps_files_path_create(buf, sizeof(buf), data, key)) { + return FAILURE; + } + if (VCWD_STAT(buf, &sbuf)) { + return FAILURE; + } + return SUCCESS; +} + + #define PS_FILES_DATA ps_files *data = PS_GET_MOD_DATA() PS_OPEN_FUNC(files) @@ -342,6 +326,24 @@ PS_READ_FUNC(files) struct stat sbuf; PS_FILES_DATA; + /* If strict mode, check session id existence */ + if (PS(use_strict_mode) && + ps_files_key_exists(data, key TSRMLS_CC) == FAILURE) { + /* key points to PS(id), but cannot change here. */ + if (key) { + efree(PS(id)); + PS(id) = NULL; + } + PS(id) = PS(mod)->s_create_sid((void **)&data, NULL TSRMLS_CC); + if (!PS(id)) { + return FAILURE; + } + php_session_reset_id(TSRMLS_C); + if (PS(use_cookies)) { + PS(send_cookie) = 1; + } + } + ps_files_open(data, key TSRMLS_CC); if (data->fd < 0) { return FAILURE; @@ -454,6 +456,17 @@ PS_GC_FUNC(files) return SUCCESS; } +PS_CREATE_SID_FUNC(files) +{ + char *sid; + PS_FILES_DATA; + + sid = php_session_create_id((void **)&data, newlen TSRMLS_CC); + + return sid; +} + + /* * Local variables: * tab-width: 4 |