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;
}
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))
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()
}
}
-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;
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;
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
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