]> granicus.if.org Git - php/commitdiff
Add INI setting session.hash_bits_per_character which enables developers
authorSascha Schumann <sas@php.net>
Thu, 16 Jan 2003 07:21:49 +0000 (07:21 +0000)
committerSascha Schumann <sas@php.net>
Thu, 16 Jan 2003 07:21:49 +0000 (07:21 +0000)
to choose how session ids are represented, regardless of the hash algorithm.

ext/session/mod_files.c
ext/session/php_session.h
ext/session/session.c
php.ini-dist
php.ini-recommended

index 011ec1f770e281bbecbe2eeb227e8f7a02a3b99c..d760156dca10ea35e5dad9721cfe896ef7e19721 100644 (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))
index 47ee8582012a23bc042ca923d51db9f9c51ba210..05a74c4ed0ef4c98a5bade94eb80479ecd326ab3 100644 (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;
index 456471efbe0ae9260910a227b268498d642675d7..44fe30c147b2ca6bd3e30a629e4bfcb8f999df43 100644 (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];
-
-                       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;
index d14255b5d09f794323c98282bfb3f3a404503c9a..282db20fccfd2fcb2573284223327053269ba9b9 100644 (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
index 023618f307b1a69b49f646639d1e9290eb75a5f2..0f69b6cfdbbf1c987a917c770a563725ebd10a27 100644 (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