summaryrefslogtreecommitdiff
path: root/ext/session
diff options
context:
space:
mode:
authorMark A. Hershberger <mah@debian.(none)>2009-03-25 00:38:07 -0400
committerMark A. Hershberger <mah@debian.(none)>2009-03-25 00:38:07 -0400
commitbb01389fbd53ec1cbcb80d0681a37cca1267891a (patch)
tree4783178fca65a5d9071c8df34f2ddc3d31728673 /ext/session
parenteddbbea4325e602ddc87c545531609132d4f0e3b (diff)
downloadphp-upstream/5.2.4.tar.gz
Imported Upstream version 5.2.4upstream/5.2.4
Diffstat (limited to 'ext/session')
-rw-r--r--ext/session/mod_files.c110
-rw-r--r--ext/session/session.c34
-rw-r--r--ext/session/tests/004.phpt2
-rw-r--r--ext/session/tests/020.phpt2
-rw-r--r--ext/session/tests/bug41600.phpt26
5 files changed, 124 insertions, 50 deletions
diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c
index 9cba9f2ef..e80e51d10 100644
--- a/ext/session/mod_files.c
+++ b/ext/session/mod_files.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: mod_files.c,v 1.100.2.3.2.5 2007/03/03 15:07:31 iliaa Exp $ */
+/* $Id: mod_files.c,v 1.100.2.3.2.9 2007/08/23 12:23:59 jani Exp $ */
#include "php.h"
@@ -87,9 +87,10 @@ static int ps_files_valid_key(const char *key)
len = p - key;
- if (len == 0)
+ if (len == 0) {
ret = 0;
-
+ }
+
return ret;
}
@@ -101,9 +102,11 @@ static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, cons
int n;
key_len = strlen(key);
- if (key_len <= data->dirdepth || buflen <
- (strlen(data->basedir) + 2 * data->dirdepth + key_len + 5 + sizeof(FILE_PREFIX)))
+ if (key_len <= data->dirdepth ||
+ buflen < (strlen(data->basedir) + 2 * data->dirdepth + key_len + 5 + sizeof(FILE_PREFIX))) {
return NULL;
+ }
+
p = key;
memcpy(buf, data->basedir, data->basedir_len);
n = data->basedir_len;
@@ -149,27 +152,49 @@ static void ps_files_open(ps_files *data, const char *key TSRMLS_DC)
}
ps_files_close(data);
-
+
if (!ps_files_valid_key(key)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id 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))
+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
return;
-
+ }
+
data->lastkey = estrdup(key);
-
- data->fd = VCWD_OPEN_MODE(buf, O_CREAT | O_RDWR | O_BINARY,
- data->filemode);
-
+
+ data->fd = VCWD_OPEN_MODE(buf, O_CREAT | O_RDWR | O_BINARY, data->filemode);
+
if (data->fd != -1) {
+#ifndef PHP_WIN32
+ /* check to make sure that the opened file is not a symlink, linking to data outside of allowable dirs */
+ if (PG(safe_mode) || PG(open_basedir)) {
+ struct stat sbuf;
+
+ if (fstat(data->fd, &sbuf)) {
+ close(data->fd);
+ return;
+ }
+ if (
+ S_ISLNK(sbuf.st_mode) &&
+ (
+ php_check_open_basedir(buf TSRMLS_CC) ||
+ (PG(safe_mode) && !php_checkuid(buf, NULL, CHECKUID_CHECK_FILE_AND_DIR))
+ )
+ ) {
+
+ close(data->fd);
+ return;
+ }
+ }
+#endif
flock(data->fd, LOCK_EX);
#ifdef F_SETFD
-#ifndef FD_CLOEXEC
-#define FD_CLOEXEC 1
-#endif
+# ifndef FD_CLOEXEC
+# define FD_CLOEXEC 1
+# endif
if (fcntl(data->fd, F_SETFD, FD_CLOEXEC)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "fcntl(%d, F_SETFD, FD_CLOEXEC) failed: %s (%d)", data->fd, strerror(errno), errno);
}
@@ -209,15 +234,16 @@ static int ps_files_cleanup_dir(const char *dirname, int maxlifetime TSRMLS_DC)
while (php_readdir_r(dir, (struct dirent *) dentry, &entry) == 0 && entry) {
/* does the file start with our prefix? */
if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1)) {
- size_t entry_len;
+ size_t entry_len = strlen(entry->d_name);
- entry_len = strlen(entry->d_name);
/* does it fit into our buffer? */
if (entry_len + dirname_len + 2 < MAXPATHLEN) {
/* create the full path.. */
memcpy(buf + dirname_len + 1, entry->d_name, entry_len);
+
/* NUL terminate it and */
buf[dirname_len + entry_len + 1] = '\0';
+
/* check whether its last access was more than maxlifet ago */
if (VCWD_STAT(buf, &sbuf) == 0 &&
#ifdef NETWARE
@@ -277,8 +303,7 @@ PS_OPEN_FUNC(files)
errno = 0;
dirdepth = (size_t) strtol(argv[0], NULL, 10);
if (errno == ERANGE) {
- php_error(E_WARNING,
- "The first parameter in session.save_path is invalid");
+ php_error(E_WARNING, "The first parameter in session.save_path is invalid");
return FAILURE;
}
}
@@ -287,8 +312,7 @@ PS_OPEN_FUNC(files)
errno = 0;
filemode = strtol(argv[1], NULL, 8);
if (errno == ERANGE || filemode < 0 || filemode > 07777) {
- php_error(E_WARNING,
- "The second parameter in session.save_path is invalid");
+ php_error(E_WARNING, "The second parameter in session.save_path is invalid");
return FAILURE;
}
}
@@ -314,8 +338,10 @@ PS_CLOSE_FUNC(files)
ps_files_close(data);
- if (data->lastkey)
+ if (data->lastkey) {
efree(data->lastkey);
+ }
+
efree(data->basedir);
efree(data);
*mod_data = NULL;
@@ -330,19 +356,21 @@ PS_READ_FUNC(files)
PS_FILES_DATA;
ps_files_open(data, key TSRMLS_CC);
- if (data->fd < 0)
+ if (data->fd < 0) {
return FAILURE;
-
- if (fstat(data->fd, &sbuf))
+ }
+
+ if (fstat(data->fd, &sbuf)) {
return FAILURE;
-
+ }
+
data->st_size = *vallen = sbuf.st_size;
-
+
if (sbuf.st_size == 0) {
*val = STR_EMPTY_ALLOC();
return SUCCESS;
}
-
+
*val = emalloc(sbuf.st_size);
#if defined(HAVE_PREAD)
@@ -353,10 +381,11 @@ PS_READ_FUNC(files)
#endif
if (n != sbuf.st_size) {
- if (n == -1)
+ if (n == -1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "read failed: %s (%d)", strerror(errno), errno);
- else
+ } else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "read returned less bytes than requested");
+ }
efree(*val);
return FAILURE;
}
@@ -370,16 +399,18 @@ PS_WRITE_FUNC(files)
PS_FILES_DATA;
ps_files_open(data, key TSRMLS_CC);
- if (data->fd < 0)
+ if (data->fd < 0) {
return FAILURE;
+ }
/*
* truncate file, if the amount of new data is smaller than
* the existing data set.
*/
- if (vallen < (int)data->st_size)
+ if (vallen < (int)data->st_size) {
ftruncate(data->fd, 0);
+ }
#if defined(HAVE_PWRITE)
n = pwrite(data->fd, val, vallen, 0);
@@ -389,10 +420,11 @@ PS_WRITE_FUNC(files)
#endif
if (n != vallen) {
- if (n == -1)
+ if (n == -1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "write failed: %s (%d)", strerror(errno), errno);
- else
+ } else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "write wrote less bytes than requested");
+ }
return FAILURE;
}
@@ -404,9 +436,10 @@ PS_DESTROY_FUNC(files)
char buf[MAXPATHLEN];
PS_FILES_DATA;
- if (!ps_files_path_create(buf, sizeof(buf), data, key))
+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
return FAILURE;
-
+ }
+
if (data->fd != -1) {
ps_files_close(data);
@@ -431,9 +464,10 @@ PS_GC_FUNC(files)
we return SUCCESS, since all cleanup should be handled by
an external entity (i.e. find -ctime x | xargs rm) */
- if (data->dirdepth == 0)
+ if (data->dirdepth == 0) {
*nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime TSRMLS_CC);
-
+ }
+
return SUCCESS;
}
diff --git a/ext/session/session.c b/ext/session/session.c
index b2a4ac7d5..9ec40f6e2 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: session.c,v 1.417.2.8.2.34 2007/05/16 01:18:14 stas Exp $ */
+/* $Id: session.c,v 1.417.2.8.2.40 2007/08/03 01:16:40 stas Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -46,6 +46,7 @@
#include "ext/standard/php_rand.h" /* for RAND_MAX */
#include "ext/standard/info.h"
#include "ext/standard/php_smart_str.h"
+#include "ext/standard/url.h"
#include "mod_files.h"
#include "mod_user.h"
@@ -150,7 +151,7 @@ static PHP_INI_MH(OnUpdateSerializer)
static PHP_INI_MH(OnUpdateSaveDir)
{
/* Only do the safemode/open_basedir check at runtime */
- if (stage == PHP_INI_STAGE_RUNTIME) {
+ if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) {
char *p;
if (memchr(new_value, '\0', new_value_length) != NULL) {
@@ -167,7 +168,7 @@ static PHP_INI_MH(OnUpdateSaveDir)
return FAILURE;
}
- if (php_check_open_basedir(p TSRMLS_CC)) {
+ if (PG(open_basedir) && php_check_open_basedir(p TSRMLS_CC)) {
return FAILURE;
}
}
@@ -946,10 +947,15 @@ static char *week_days[] = {
static void strcpy_gmt(char *ubuf, time_t *when)
{
char buf[MAX_STR];
- struct tm tm;
+ struct tm tm, *res;
int n;
- php_gmtime_r(when, &tm);
+ res = php_gmtime_r(when, &tm);
+
+ if (!res) {
+ buf[0] = '\0';
+ return;
+ }
n = slprintf(buf, sizeof(buf), "%s, %02d %s %d %02d:%02d:%02d GMT", /* SAFE */
week_days[tm.tm_wday], tm.tm_mday,
@@ -1075,6 +1081,7 @@ static void php_session_send_cookie(TSRMLS_D)
{
smart_str ncookie = {0};
char *date_fmt = NULL;
+ char *e_session_name, *e_id;
if (SG(headers_sent)) {
char *output_start_filename = php_get_output_start_filename(TSRMLS_C);
@@ -1088,11 +1095,18 @@ static void php_session_send_cookie(TSRMLS_D)
}
return;
}
+
+ /* URL encode session_name and id because they might be user supplied */
+ e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)), NULL);
+ e_id = php_url_encode(PS(id), strlen(PS(id)), NULL);
smart_str_appends(&ncookie, COOKIE_SET_COOKIE);
- smart_str_appends(&ncookie, PS(session_name));
+ smart_str_appends(&ncookie, e_session_name);
smart_str_appendc(&ncookie, '=');
- smart_str_appends(&ncookie, PS(id));
+ smart_str_appends(&ncookie, e_id);
+
+ efree(e_session_name);
+ efree(e_id);
if (PS(cookie_lifetime) > 0) {
struct timeval tv;
@@ -1207,10 +1221,7 @@ PHPAPI void php_session_start(TSRMLS_D)
PS(apply_trans_sid) = PS(use_trans_sid);
- PS(define_sid) = 1;
- PS(send_cookie) = 1;
if (PS(session_status) != php_session_none) {
-
if (PS(session_status) == php_session_disabled) {
char *value;
@@ -1227,6 +1238,9 @@ PHPAPI void php_session_start(TSRMLS_D)
php_error(E_NOTICE, "A session had already been started - ignoring session_start()");
return;
+ } else {
+ PS(define_sid) = 1;
+ PS(send_cookie) = 1;
}
lensess = strlen(PS(session_name));
diff --git a/ext/session/tests/004.phpt b/ext/session/tests/004.phpt
index 2040476bc..b9013cac7 100644
--- a/ext/session/tests/004.phpt
+++ b/ext/session/tests/004.phpt
@@ -13,7 +13,7 @@ session.serialize_handler=php
error_reporting(E_ALL);
class handler {
- public $data = 'baz|O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:1;}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:1;}}';
+ public $data = 'baz|O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:1;}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:1;}}';
function open($save_path, $session_name)
{
print "OPEN: $session_name\n";
diff --git a/ext/session/tests/020.phpt b/ext/session/tests/020.phpt
index 455c7f720..82997a8f0 100644
--- a/ext/session/tests/020.phpt
+++ b/ext/session/tests/020.phpt
@@ -6,7 +6,7 @@ rewriter uses arg_seperator.output for modifying URLs
session.use_cookies=0
session.cache_limiter=
session.use_trans_sid=1
-arg_separator.output=&amp;
+arg_separator.output="&amp;"
session.name=PHPSESSID
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/bug41600.phpt b/ext/session/tests/bug41600.phpt
new file mode 100644
index 000000000..ba04fd9d9
--- /dev/null
+++ b/ext/session/tests/bug41600.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #41600 (url rewriter tags doesn't work with namespaced tags)
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--INI--
+session.use_cookies=0
+session.cache_limiter=
+session.use_trans_sid=1
+arg_separator.output=&amp;
+session.name=PHPSESSID
+session.serialize_handler=php
+session.save_handler=files
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+session_id("abtest");
+session_start();
+?>
+<a href="link.php?a=b">
+<?php
+session_destroy();
+?>
+--EXPECT--
+<a href="link.php?a=b&amp;PHPSESSID=abtest">