diff options
author | Sascha Schumann <sas@php.net> | 2003-01-16 07:21:49 +0000 |
---|---|---|
committer | Sascha Schumann <sas@php.net> | 2003-01-16 07:21:49 +0000 |
commit | db8b4c67629334da8daad5ce28d51f8f644ef113 (patch) | |
tree | 2a46ff4125183a9006da1480ced0c4cb8907e091 | |
parent | 4e53357e9bab7ac8a22218f283213f8a4bec7fbf (diff) | |
download | php-git-db8b4c67629334da8daad5ce28d51f8f644ef113.tar.gz |
Add INI setting session.hash_bits_per_character which enables developers
to choose how session ids are represented, regardless of the hash algorithm.
-rw-r--r-- | ext/session/mod_files.c | 10 | ||||
-rw-r--r-- | ext/session/php_session.h | 1 | ||||
-rw-r--r-- | ext/session/session.c | 84 | ||||
-rw-r--r-- | php.ini-dist | 12 | ||||
-rw-r--r-- | php.ini-recommended | 14 |
5 files changed, 82 insertions, 39 deletions
diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 011ec1f770..d760156dca 100644 --- a/ext/session/mod_files.c +++ b/ext/session/mod_files.c @@ -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)) diff --git a/ext/session/php_session.h b/ext/session/php_session.h index 47ee858201..05a74c4ed0 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -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; diff --git a/ext/session/session.c b/ext/session/session.c index 456471efbe..44fe30c147 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -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]; - - 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; + if (PS(hash_bits_per_character) < 4 + || PS(hash_bits_per_character) > 6) { + PS(hash_bits_per_character) = 4; - 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; diff --git a/php.ini-dist b/php.ini-dist index d14255b5d0..282db20fcc 100644 --- a/php.ini-dist +++ b/php.ini-dist @@ -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 diff --git a/php.ini-recommended b/php.ini-recommended index 023618f307..0f69b6cfdb 100644 --- a/php.ini-recommended +++ b/php.ini-recommended @@ -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 |