258 */ |
258 */ |
259 |
259 |
260 function __construct() |
260 function __construct() |
261 { |
261 { |
262 global $db, $session, $paths, $template, $plugins; // Common objects |
262 global $db, $session, $paths, $template, $plugins; // Common objects |
263 include(ENANO_ROOT.'/config.php'); |
263 |
|
264 if ( defined('IN_ENANO_INSTALL') ) |
|
265 { |
|
266 @include(ENANO_ROOT.'/config.new.php'); |
|
267 } |
|
268 else |
|
269 { |
|
270 @include(ENANO_ROOT.'/config.php'); |
|
271 } |
|
272 |
264 unset($dbhost, $dbname, $dbuser, $dbpasswd); |
273 unset($dbhost, $dbname, $dbuser, $dbpasswd); |
265 if(isset($crypto_key)) |
274 if(isset($crypto_key)) |
266 { |
275 { |
267 $this->private_key = $crypto_key; |
276 $this->private_key = $crypto_key; |
268 $this->private_key = hexdecode($this->private_key); |
277 $this->private_key = hexdecode($this->private_key); |
561 * @param array $captcha_hash Optional. If we're locked out and the lockout policy is captcha, this should be the identifier for the code. |
570 * @param array $captcha_hash Optional. If we're locked out and the lockout policy is captcha, this should be the identifier for the code. |
562 * @param array $captcha_code Optional. If we're locked out and the lockout policy is captcha, this should be the code the user entered. |
571 * @param array $captcha_code Optional. If we're locked out and the lockout policy is captcha, this should be the code the user entered. |
563 * @return string 'success' on success, or error string on failure |
572 * @return string 'success' on success, or error string on failure |
564 */ |
573 */ |
565 |
574 |
566 function login_with_crypto($username, $aes_data, $aes_key, $challenge, $level = USER_LEVEL_MEMBER, $captcha_hash = false, $captcha_code = false) |
575 function login_with_crypto($username, $aes_data, $aes_key_id, $challenge, $level = USER_LEVEL_MEMBER, $captcha_hash = false, $captcha_code = false) |
567 { |
576 { |
568 global $db, $session, $paths, $template, $plugins; // Common objects |
577 global $db, $session, $paths, $template, $plugins; // Common objects |
569 |
578 |
570 $privcache = $this->private_key; |
579 $privcache = $this->private_key; |
571 |
580 |
634 |
643 |
635 // Initialize our success switch |
644 // Initialize our success switch |
636 $success = false; |
645 $success = false; |
637 |
646 |
638 // Escaped username |
647 // Escaped username |
|
648 $username = str_replace('_', ' ', $username); |
639 $db_username_lower = $this->prepare_text(strtolower($username)); |
649 $db_username_lower = $this->prepare_text(strtolower($username)); |
640 $db_username = $this->prepare_text($username); |
650 $db_username = $this->prepare_text($username); |
641 |
651 |
642 // Select the user data from the table, and decrypt that so we can verify the password |
652 // Select the user data from the table, and decrypt that so we can verify the password |
643 $this->sql('SELECT password,old_encryption,user_id,user_level,theme,style,temp_password,temp_password_time FROM '.table_prefix.'users WHERE lcase(username)=\''.$db_username_lower.'\' OR username=\'' . $db_username . '\';'); |
653 $this->sql('SELECT password,old_encryption,user_id,user_level,theme,style,temp_password,temp_password_time FROM '.table_prefix.'users WHERE lcase(username)=\''.$db_username_lower.'\' OR username=\'' . $db_username . '\';'); |
799 function login_without_crypto($username, $password, $already_md5ed = false, $level = USER_LEVEL_MEMBER) |
809 function login_without_crypto($username, $password, $already_md5ed = false, $level = USER_LEVEL_MEMBER) |
800 { |
810 { |
801 global $db, $session, $paths, $template, $plugins; // Common objects |
811 global $db, $session, $paths, $template, $plugins; // Common objects |
802 |
812 |
803 $pass_hashed = ( $already_md5ed ) ? $password : md5($password); |
813 $pass_hashed = ( $already_md5ed ) ? $password : md5($password); |
|
814 |
|
815 // Replace underscores with spaces in username |
|
816 // (Added in 1.0.2) |
|
817 $username = str_replace('_', ' ', $username); |
804 |
818 |
805 // Perhaps we're upgrading Enano? |
819 // Perhaps we're upgrading Enano? |
806 if($this->compat) |
820 if($this->compat) |
807 { |
821 { |
808 return $this->login_compat($username, $pass_hashed, $level); |
822 return $this->login_compat($username, $pass_hashed, $level); |
1082 $query = $this->sql('INSERT INTO '.table_prefix.'session_keys(session_key, salt, user_id, auth_level, source_ip, time) VALUES(\''.$keyhash.'\', \''.$salt.'\', '.$user_id.', '.$level.', \''.$ip.'\', '.$time.');'); |
1096 $query = $this->sql('INSERT INTO '.table_prefix.'session_keys(session_key, salt, user_id, auth_level, source_ip, time) VALUES(\''.$keyhash.'\', \''.$salt.'\', '.$user_id.', '.$level.', \''.$ip.'\', '.$time.');'); |
1083 return true; |
1097 return true; |
1084 } |
1098 } |
1085 |
1099 |
1086 /** |
1100 /** |
1087 * Identical to register_session in nature, but uses the old login/table structure. DO NOT use this. |
1101 * 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. |
1088 * @see sessionManager::register_session() |
1102 * @see sessionManager::register_session() |
1089 * @access private |
1103 * @access private |
1090 */ |
1104 */ |
1091 |
1105 |
1092 function register_session_compat($user_id, $username, $password, $level = 0) |
1106 function register_session_compat($user_id, $username, $password, $level = 0) |
1534 */ |
1548 */ |
1535 |
1549 |
1536 function check_banlist() |
1550 function check_banlist() |
1537 { |
1551 { |
1538 global $db, $session, $paths, $template, $plugins; // Common objects |
1552 global $db, $session, $paths, $template, $plugins; // Common objects |
1539 if($this->compat) |
1553 $col_reason = ( $this->compat ) ? '"No reason entered (session manager is in compatibility mode)" AS reason' : 'reason'; |
1540 $q = $this->sql('SELECT ban_id,ban_type,ban_value,is_regex FROM '.table_prefix.'banlist ORDER BY ban_type;'); |
1554 $is_banned = false; |
1541 else |
1555 if ( $this->user_logged_in ) |
1542 $q = $this->sql('SELECT ban_id,ban_type,ban_value,is_regex,reason FROM '.table_prefix.'banlist ORDER BY ban_type;'); |
1556 { |
1543 if(!$q) $db->_die('The banlist data could not be selected.'); |
1557 // check by IP, email, and username |
1544 $banned = false; |
1558 $sql = "SELECT $col_reason, ban_value, ban_type, is_regex FROM " . table_prefix . "banlist WHERE \n" |
1545 while($row = $db->fetchrow()) |
1559 . " ( ban_type = " . BAN_IP . " AND is_regex = 0 ) OR \n" |
1546 { |
1560 . " ( ban_type = " . BAN_IP . " AND is_regex = 1 AND '{$_SERVER['REMOTE_ADDR']}' REGEXP ban_value ) OR \n" |
1547 if($this->compat) |
1561 . " ( ban_type = " . BAN_USER . " AND is_regex = 0 AND ban_value = '{$this->username}' ) OR \n" |
1548 $row['reason'] = 'None available - session manager is in compatibility mode'; |
1562 . " ( ban_type = " . BAN_USER . " AND is_regex = 1 AND '{$this->username}' REGEXP ban_value ) OR \n" |
1549 switch($row['ban_type']) |
1563 . " ( ban_type = " . BAN_EMAIL . " AND is_regex = 0 AND ban_value = '{$this->email}' ) OR \n" |
1550 { |
1564 . " ( ban_type = " . BAN_EMAIL . " AND is_regex = 1 AND '{$this->email}' REGEXP ban_value ) \n" |
1551 case BAN_IP: |
1565 . " ORDER BY ban_type ASC;"; |
1552 if(intval($row['is_regex'])==1) { |
1566 $q = $this->sql($sql); |
1553 if(preg_match('#'.$row['ban_value'].'#i', $_SERVER['REMOTE_ADDR'])) |
1567 if ( $db->numrows() > 0 ) |
|
1568 { |
|
1569 while ( list($reason, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) |
|
1570 { |
|
1571 if ( $ban_type == BAN_IP && $row['is_regex'] != 1 ) |
1554 { |
1572 { |
|
1573 // check range |
|
1574 $regexp = parse_ip_range_regex($ban_value); |
|
1575 if ( !$regexp ) |
|
1576 { |
|
1577 continue; |
|
1578 } |
|
1579 if ( preg_match("/$regexp/", $_SERVER['REMOTE_ADDR']) ) |
|
1580 { |
|
1581 $banned = true; |
|
1582 } |
|
1583 } |
|
1584 else |
|
1585 { |
|
1586 // User is banned |
1555 $banned = true; |
1587 $banned = true; |
1556 $reason = $row['reason']; |
|
1557 } |
1588 } |
1558 } |
1589 } |
1559 else { |
1590 } |
1560 if($row['ban_value']==$_SERVER['REMOTE_ADDR']) { $banned = true; $reason = $row['reason']; } |
1591 $db->free_result(); |
1561 } |
1592 } |
1562 break; |
1593 else |
1563 case BAN_USER: |
1594 { |
1564 if(intval($row['is_regex'])==1) { |
1595 // check by IP only |
1565 if(preg_match('#'.$row['ban_value'].'#i', $this->username)) |
1596 $sql = "SELECT $col_reason, ban_value, ban_type, is_regex FROM " . table_prefix . "banlist WHERE |
|
1597 ( ban_type = " . BAN_IP . " AND is_regex = 0 ) OR |
|
1598 ( ban_type = " . BAN_IP . " AND is_regex = 1 AND '{$_SERVER['REMOTE_ADDR']}' REGEXP ban_value ) |
|
1599 ORDER BY ban_type ASC;"; |
|
1600 $q = $this->sql($sql); |
|
1601 if ( $db->numrows() > 0 ) |
|
1602 { |
|
1603 while ( list($reason, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) |
|
1604 { |
|
1605 if ( $ban_type == BAN_IP && $row['is_regex'] != 1 ) |
1566 { |
1606 { |
|
1607 // check range |
|
1608 $regexp = parse_ip_range_regex($ban_value); |
|
1609 if ( !$regexp ) |
|
1610 continue; |
|
1611 if ( preg_match("/$regexp/", $_SERVER['REMOTE_ADDR']) ) |
|
1612 { |
|
1613 $banned = true; |
|
1614 } |
|
1615 } |
|
1616 else |
|
1617 { |
|
1618 // User is banned |
1567 $banned = true; |
1619 $banned = true; |
1568 $reason = $row['reason']; |
|
1569 } |
1620 } |
1570 } |
1621 } |
1571 else { |
1622 } |
1572 if($row['ban_value']==$this->username) { $banned = true; $reason = $row['reason']; } |
1623 $db->free_result(); |
1573 } |
1624 } |
1574 break; |
1625 if ( $banned && $paths->get_pageid_from_url() != $paths->nslist['Special'].'CSS' ) |
1575 case BAN_EMAIL: |
|
1576 if(intval($row['is_regex'])==1) { |
|
1577 if(preg_match('#'.$row['ban_value'].'#i', $this->email)) |
|
1578 { |
|
1579 $banned = true; |
|
1580 $reason = $row['reason']; |
|
1581 } |
|
1582 } |
|
1583 else { |
|
1584 if($row['ban_value']==$this->email) { $banned = true; $reason = $row['reason']; } |
|
1585 } |
|
1586 break; |
|
1587 default: |
|
1588 die('Ban error: rule "'.$row['ban_value'].'" has an invalid type ('.$row['ban_type'].')'); |
|
1589 } |
|
1590 } |
|
1591 if($banned && $paths->get_pageid_from_url() != $paths->nslist['Special'].'CSS') |
|
1592 { |
1626 { |
1593 // This guy is banned - kill the session, kill the database connection, bail out, and be pretty about it |
1627 // This guy is banned - kill the session, kill the database connection, bail out, and be pretty about it |
1594 die_semicritical('Ban notice', '<div class="error-box">You have been banned from this website. Please contact the site administrator for more information.<br /><br />Reason:<br />'.$reason.'</div>'); |
1628 die_semicritical('Ban notice', '<div class="error-box">You have been banned from this website. Please contact the site administrator for more information.<br /><br />Reason:<br />'.$reason.'</div>'); |
1595 exit; |
1629 exit; |
1596 } |
1630 } |
1598 |
1632 |
1599 # Registration |
1633 # Registration |
1600 |
1634 |
1601 /** |
1635 /** |
1602 * Registers a user. This does not perform any type of login. |
1636 * Registers a user. This does not perform any type of login. |
1603 * @param string $username |
1637 * @param string New user's username |
1604 * @param string $password This should be unencrypted. |
1638 * @param string This should be unencrypted. |
1605 * @param string $email |
1639 * @param string E-mail address. |
1606 * @param string $real_name Optional, defaults to ''. |
1640 * @param string Optional, defaults to ''. |
1607 * @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. |
1641 * @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. |
1608 */ |
1642 */ |
1609 |
1643 |
1610 function create_user($username, $password, $email, $real_name = '', $coppa = false) |
1644 function create_user($username, $password, $email, $real_name = '', $coppa = false) |
1611 { |
1645 { |
1612 global $db, $session, $paths, $template, $plugins; // Common objects |
1646 global $db, $session, $paths, $template, $plugins; // Common objects |
1613 |
1647 |
1614 // Initialize AES |
1648 // Initialize AES |
1615 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
1649 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
1616 |
1650 |
1617 if(!preg_match('#^'.$this->valid_username.'$#', $username)) return 'The username you chose contains invalid characters.'; |
1651 if(!preg_match('#^'.$this->valid_username.'$#', $username)) return 'The username you chose contains invalid characters.'; |
|
1652 $username = str_replace('_', ' ', $username); |
1618 $user_orig = $username; |
1653 $user_orig = $username; |
1619 $username = $this->prepare_text($username); |
1654 $username = $this->prepare_text($username); |
1620 $email = $this->prepare_text($email); |
1655 $email = $this->prepare_text($email); |
1621 $real_name = $this->prepare_text($real_name); |
1656 $real_name = $this->prepare_text($real_name); |
1622 |
1657 |