diff -r 06db76725891 -r 5bcdee999015 includes/sessions.php --- a/includes/sessions.php Sat Nov 17 23:30:23 2007 -0500 +++ b/includes/sessions.php Sun Nov 18 18:44:55 2007 -0500 @@ -151,7 +151,7 @@ */ //var $valid_username = '([A-Za-z0-9 \!\@\(\)-]+)'; - var $valid_username = '([^<>_&\?\'"%\n\r\t\a\/]+)'; + var $valid_username = '([^<>&\?\'"%\n\r\t\a\/]+)'; /** * What we're allowed to do as far as permissions go. This changes based on the value of the "auth" URI param. @@ -559,7 +559,7 @@ * @return string 'success' on success, or error string on failure */ - function login_with_crypto($username, $aes_data, $aes_key, $challenge, $level = USER_LEVEL_MEMBER) + function login_with_crypto($username, $aes_data, $aes_key_id, $challenge, $level = USER_LEVEL_MEMBER) { global $db, $session, $paths, $template, $plugins; // Common objects @@ -570,9 +570,9 @@ // Fetch our decryption key - $aes_key = $this->fetch_public_key($aes_key); + $aes_key = $this->fetch_public_key($aes_key_id); if(!$aes_key) - return 'Couldn\'t look up public key "'.$aes_key.'" for decryption'; + return 'Couldn\'t look up public key "'.htmlspecialchars($aes_key_id).'" for decryption'; // Convert the key to a binary string $bin_key = hexdecode($aes_key); @@ -587,6 +587,7 @@ $success = false; // Escaped username + $username = str_replace('_', ' ', $username); $db_username_lower = $this->prepare_text(strtolower($username)); $db_username = $this->prepare_text($username); @@ -702,6 +703,10 @@ $pass_hashed = ( $already_md5ed ) ? $password : md5($password); + // Replace underscores with spaces in username + // (Added in 1.0.2) + $username = str_replace('_', ' ', $username); + // Perhaps we're upgrading Enano? if($this->compat) { @@ -837,7 +842,7 @@ /** * Registers a session key in the database. This function *ASSUMES* that the username and password have already been validated! - * Basically the session key is a base64-encoded cookie (encrypted with the site's private key) that says "u=[username];p=[sha1 of password]" + * Basically the session key is a hex-encoded cookie (encrypted with the site's private key) that says "u=[username];p=[sha1 of password];s=[unique key id]" * @param int $user_id * @param string $username * @param string $password @@ -896,7 +901,7 @@ } /** - * Identical to register_session in nature, but uses the old login/table structure. DO NOT use this. + * Identical to register_session in nature, but uses the old login/table structure. DO NOT use this except in the upgrade script under very controlled circumstances. * @see sessionManager::register_session() * @access private */ @@ -1338,59 +1343,79 @@ function check_banlist() { global $db, $session, $paths, $template, $plugins; // Common objects - if($this->compat) - $q = $this->sql('SELECT ban_id,ban_type,ban_value,is_regex FROM '.table_prefix.'banlist ORDER BY ban_type;'); - else - $q = $this->sql('SELECT ban_id,ban_type,ban_value,is_regex,reason FROM '.table_prefix.'banlist ORDER BY ban_type;'); - if(!$q) $db->_die('The banlist data could not be selected.'); - $banned = false; - while($row = $db->fetchrow()) + $col_reason = ( $this->compat ) ? '"No reason entered (session manager is in compatibility mode)" AS reason' : 'reason'; + $is_banned = false; + if ( $this->user_logged_in ) { - if($this->compat) - $row['reason'] = 'None available - session manager is in compatibility mode'; - switch($row['ban_type']) + // check by IP, email, and username + $sql = "SELECT $col_reason, ban_value, ban_type, is_regex FROM " . table_prefix . "banlist WHERE \n" + . " ( ban_type = " . BAN_IP . " AND is_regex = 0 ) OR \n" + . " ( ban_type = " . BAN_IP . " AND is_regex = 1 AND '{$_SERVER['REMOTE_ADDR']}' REGEXP ban_value ) OR \n" + . " ( ban_type = " . BAN_USER . " AND is_regex = 0 AND ban_value = '{$this->username}' ) OR \n" + . " ( ban_type = " . BAN_USER . " AND is_regex = 1 AND '{$this->username}' REGEXP ban_value ) OR \n" + . " ( ban_type = " . BAN_EMAIL . " AND is_regex = 0 AND ban_value = '{$this->email}' ) OR \n" + . " ( ban_type = " . BAN_EMAIL . " AND is_regex = 1 AND '{$this->email}' REGEXP ban_value ) \n" + . " ORDER BY ban_type ASC;"; + $q = $this->sql($sql); + if ( $db->numrows() > 0 ) { - case BAN_IP: - if(intval($row['is_regex'])==1) { - if(preg_match('#'.$row['ban_value'].'#i', $_SERVER['REMOTE_ADDR'])) + while ( list($reason, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) + { + if ( $ban_type == BAN_IP && $row['is_regex'] != 1 ) { + // check range + $regexp = parse_ip_range_regex($ban_value); + if ( !$regexp ) + { + continue; + } + if ( preg_match("/$regexp/", $_SERVER['REMOTE_ADDR']) ) + { + $banned = true; + } + } + else + { + // User is banned $banned = true; - $reason = $row['reason']; } } - else { - if($row['ban_value']==$_SERVER['REMOTE_ADDR']) { $banned = true; $reason = $row['reason']; } - } - break; - case BAN_USER: - if(intval($row['is_regex'])==1) { - if(preg_match('#'.$row['ban_value'].'#i', $this->username)) + } + $db->free_result(); + } + else + { + // check by IP only + $sql = "SELECT $col_reason, ban_value, ban_type, is_regex FROM " . table_prefix . "banlist WHERE + ( ban_type = " . BAN_IP . " AND is_regex = 0 ) OR + ( ban_type = " . BAN_IP . " AND is_regex = 1 AND '{$_SERVER['REMOTE_ADDR']}' REGEXP ban_value ) + ORDER BY ban_type ASC;"; + $q = $this->sql($sql); + if ( $db->numrows() > 0 ) + { + while ( list($reason, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) + { + if ( $ban_type == BAN_IP && $row['is_regex'] != 1 ) { + // check range + $regexp = parse_ip_range_regex($ban_value); + if ( !$regexp ) + continue; + if ( preg_match("/$regexp/", $_SERVER['REMOTE_ADDR']) ) + { + $banned = true; + } + } + else + { + // User is banned $banned = true; - $reason = $row['reason']; } } - else { - if($row['ban_value']==$this->username) { $banned = true; $reason = $row['reason']; } - } - break; - case BAN_EMAIL: - if(intval($row['is_regex'])==1) { - if(preg_match('#'.$row['ban_value'].'#i', $this->email)) - { - $banned = true; - $reason = $row['reason']; - } - } - else { - if($row['ban_value']==$this->email) { $banned = true; $reason = $row['reason']; } - } - break; - default: - die('Ban error: rule "'.$row['ban_value'].'" has an invalid type ('.$row['ban_type'].')'); } + $db->free_result(); } - if($banned && $paths->get_pageid_from_url() != $paths->nslist['Special'].'CSS') + if ( $banned && $paths->get_pageid_from_url() != $paths->nslist['Special'].'CSS' ) { // This guy is banned - kill the session, kill the database connection, bail out, and be pretty about it die_semicritical('Ban notice', '
You have been banned from this website. Please contact the site administrator for more information.

Reason:
'.$reason.'
'); @@ -1402,11 +1427,11 @@ /** * Registers a user. This does not perform any type of login. - * @param string $username - * @param string $password This should be unencrypted. - * @param string $email - * @param string $real_name Optional, defaults to ''. - * @param bool $coppa Optional. If true, the account is not activated initially and an admin activation request is sent. The caller is responsible for sending the address info and notice. + * @param string New user's username + * @param string This should be unencrypted. + * @param string E-mail address. + * @param string Optional, defaults to ''. + * @param bool Optional. If true, the account is not activated initially and an admin activation request is sent. The caller is responsible for sending the address info and notice. */ function create_user($username, $password, $email, $real_name = '', $coppa = false) @@ -1417,6 +1442,7 @@ $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); if(!preg_match('#^'.$this->valid_username.'$#', $username)) return 'The username you chose contains invalid characters.'; + $username = str_replace('_', ' ', $username); $user_orig = $username; $username = $this->prepare_text($username); $email = $this->prepare_text($email);