Add INI setting session.hash_bits_per_character which enables developers

to choose how session ids are represented, regardless of the hash algorithm.
This commit is contained in:
Sascha Schumann 2003-01-16 07:21:49 +00:00
parent 4e53357e9b
commit db8b4c6762
5 changed files with 82 additions and 39 deletions

View file

@ -73,9 +73,11 @@ static int ps_files_valid_key(const char *key)
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'))) {
if (!((c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9')
|| c == ','
|| c == '-')) {
ret = 0;
break;
}
@ -142,7 +144,7 @@ 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 only a-z, A-Z and 0-9");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'");
return;
}
if (!ps_files_path_create(buf, sizeof(buf), data, key))

View file

@ -120,6 +120,7 @@ typedef struct _php_ps_globals {
zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
long hash_func;
long hash_bits_per_character;
} php_ps_globals;
typedef php_ps_globals zend_ps_globals;

View file

@ -153,6 +153,8 @@ PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("session.cache_expire", "180", PHP_INI_ALL, OnUpdateInt, cache_expire, php_ps_globals, ps_globals)
STD_PHP_INI_BOOLEAN("session.use_trans_sid", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, use_trans_sid, php_ps_globals, ps_globals)
STD_PHP_INI_ENTRY("session.hash_function", "0", PHP_INI_ALL, OnUpdateInt, hash_func, php_ps_globals, ps_globals)
STD_PHP_INI_ENTRY("session.hash_bits_per_character", "4", PHP_INI_ALL, OnUpdateInt, hash_bits_per_character, php_ps_globals, ps_globals)
/* Commented out until future discussion */
/* PHP_INI_ENTRY("session.encode_sources", "globals,track", PHP_INI_ALL, NULL) */
PHP_INI_END()
@ -536,25 +538,67 @@ static void php_session_decode(const char *val, int vallen TSRMLS_DC)
}
}
static char hexconvtab[] = "0123456789abcdefghijklmnopqrstuvwxyz";
/*
* Note that we cannot use the BASE64 alphabet here, because
* it contains "/" and "+": both are unacceptable for simple inclusion
* into URLs.
*/
static char hexconvtab[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-";
enum {
PS_HASH_FUNC_MD5,
PS_HASH_FUNC_SHA1
};
/* returns a pointer to the byte after the last valid character in out */
static char *bin_to_readable(char *in, size_t inlen, char *out, char nbits)
{
unsigned char *p, *q;
unsigned short w;
int mask;
int have;
p = in;
q = in + inlen;
w = 0;
have = 0;
mask = (1 << nbits) - 1;
while (1) {
if (have < nbits) {
if (p < q) {
w |= *p++ << have;
have += 8;
} else {
/* consumed everything? */
if (have == 0) break;
/* No? We need a final round */
have = nbits;
}
}
/* consume nbits */
*out++ = hexconvtab[w & mask];
w >>= nbits;
have -= nbits;
}
*out = '\0';
return out;
}
char *php_session_create_id(PS_CREATE_SID_ARGS)
{
PHP_MD5_CTX md5_context;
PHP_SHA1_CTX sha1_context;
unsigned char digest[21];
int digest_len;
int j;
char *buf;
struct timeval tv;
int i;
int j = 0;
unsigned char c;
unsigned int w;
zval **array;
zval **token;
char *remote_addr = NULL;
@ -628,33 +672,13 @@ char *php_session_create_id(PS_CREATE_SID_ARGS)
break;
}
if (digest_len == 16) {
for (i = 0; i < digest_len; i++) {
c = digest[i];
if (PS(hash_bits_per_character) < 4
|| PS(hash_bits_per_character) > 6) {
PS(hash_bits_per_character) = 4;
buf[j++] = hexconvtab[c >> 4];
buf[j++] = hexconvtab[c & 15];
}
} else {
int bit_offset, off2, off3;
/* take 5 bits from the bit stream per iteration */
/* ensure that there is a NUL byte at the end */
digest[digest_len] = 0;
for (i = 0; i < digest_len * 8 / 5; i++) {
bit_offset = i * 5;
off2 = bit_offset >> 3;
off3 = bit_offset & 7;
w = digest[off2] + (digest[off2+1] << 8);
w = (w >> off3) & 31;
buf[j++] = hexconvtab[w];
}
php_error(E_WARNING, "The ini setting hash_bits_per_character is out of range (should be 4, 5, or 6) - using 4 for now");
}
buf[j] = '\0';
j = bin_to_readable(digest, digest_len, buf, PS(hash_bits_per_character)) - buf;
if (newlen)
*newlen = j;

View file

@ -897,10 +897,18 @@ session.cache_expire = 180
session.use_trans_sid = 0
; Select a hash function
; 0: MD5 (128 bits, 32 characters, [0-9a-f])
; 1: SHA-1 (160 bits, 32 characters, [0-9a-v])
; 0: MD5 (128 bits)
; 1: SHA-1 (160 bits)
session.hash_function = 0
; Define how many bits are stored in each character when converting
; the binary hash data to something readable.
;
; 4 bits: 0-9, a-f
; 5 bits: 0-9, a-v
; 6 bits: 0-9, a-z, A-Z, "-", ","
session.hash_bits_per_character = 4
; The URL rewriter will look for URLs in a defined set of HTML tags.
; form/fieldset are special; if you include them here, the rewriter will
; add a hidden <input> field with the info which is otherwise appended

View file

@ -892,9 +892,17 @@ session.cache_expire = 180
session.use_trans_sid = 0
; Select a hash function
; 0: MD5 (128 bits, 32 characters, alphabet [0-9a-f])
; 1: SHA-1 (160 bits, 32 characters, alphabet [0-9a-v])
session.hash_function = 1
; 0: MD5 (128 bits)
; 1: SHA-1 (160 bits)
session.hash_function = 0
; Define how many bits are stored in each character when converting
; the binary hash data to something readable.
;
; 4 bits: 0-9, a-f
; 5 bits: 0-9, a-v
; 6 bits: 0-9, a-z, A-Z, "-", ","
session.hash_bits_per_character = 5
; The URL rewriter will look for URLs in a defined set of HTML tags.
; form/fieldset are special; if you include them here, the rewriter will