diff options
author | Stanislav Malyshev <stas@php.net> | 2013-08-04 20:00:28 -0700 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2013-08-04 20:00:28 -0700 |
commit | 6f73a0c00f0577313897e455f6fd729cfaa97f3b (patch) | |
tree | d87d7ac5d44fe0efee9dc428a21d32b593f67a62 /ext/session/mod_files.c | |
parent | 7d3fa7d8b6df6e1fcef1ea06db8e0ee8215c11ed (diff) | |
parent | b80d73ce154e7f740f9ada446f45dbcdac38a64b (diff) | |
download | php-git-6f73a0c00f0577313897e455f6fd729cfaa97f3b.tar.gz |
Merge branch 'pr368' into PHP-5.5
* pr368:
fix crash, enable session_id and fix test
Strict session. Detect session id collision
Strict session
Diffstat (limited to 'ext/session/mod_files.c')
-rw-r--r-- | ext/session/mod_files.c | 94 |
1 files changed, 60 insertions, 34 deletions
diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 053c617dec..e5733b44f4 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,30 @@ PS_GC_FUNC(files) return SUCCESS; } +PS_CREATE_SID_FUNC(files) +{ + char *sid; + int maxfail = 3; + PS_FILES_DATA; + + do { + sid = php_session_create_id((void **)&data, newlen TSRMLS_CC); + /* Check collision */ + if (data && ps_files_key_exists(data, sid TSRMLS_CC) == SUCCESS) { + if (sid) { + efree(sid); + sid = NULL; + } + if (!(maxfail--)) { + return NULL; + } + } + } while(!sid); + + return sid; +} + + /* * Local variables: * tab-width: 4 |