summaryrefslogtreecommitdiff
path: root/ext/session/mod_files.c
diff options
context:
space:
mode:
authorYasuo Ohgaki <yohgaki@php.net>2013-06-25 19:47:04 +0900
committerStanislav Malyshev <stas@php.net>2013-08-04 16:36:45 -0700
commit25e8fcc88fa20dc9d4c47184471003f436927cde (patch)
treeac295c6a34592e66a408a323fc1773c5f88d5099 /ext/session/mod_files.c
parentc793a6569013f9ab46f2cd7331cc1a04aa42cbed (diff)
downloadphp-git-25e8fcc88fa20dc9d4c47184471003f436927cde.tar.gz
Strict session
Diffstat (limited to 'ext/session/mod_files.c')
-rw-r--r--ext/session/mod_files.c81
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