1 <?php |
1 <?php |
2 |
2 |
3 /* |
3 /* |
4 * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between |
4 * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between |
5 * Version 1.0.2 (Coblynau) |
5 * Version 1.0.3 (Dyrad) |
6 * Copyright (C) 2006-2007 Dan Fuhry |
6 * Copyright (C) 2006-2007 Dan Fuhry |
7 * sessions.php - everything related to security and user management |
7 * sessions.php - everything related to security and user management |
8 * |
8 * |
9 * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License |
9 * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License |
10 * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
10 * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
661 $username = str_replace('_', ' ', $username); |
661 $username = str_replace('_', ' ', $username); |
662 $db_username_lower = $this->prepare_text(strtolower($username)); |
662 $db_username_lower = $this->prepare_text(strtolower($username)); |
663 $db_username = $this->prepare_text($username); |
663 $db_username = $this->prepare_text($username); |
664 |
664 |
665 // Select the user data from the table, and decrypt that so we can verify the password |
665 // Select the user data from the table, and decrypt that so we can verify the password |
666 $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 . '\';'); |
666 $this->sql('SELECT password,old_encryption,user_id,user_level,theme,style,temp_password,temp_password_time FROM '.table_prefix.'users WHERE ' . ENANO_SQLFUNC_LOWERCASE . '(username)=\''.$db_username_lower.'\' OR username=\'' . $db_username . '\';'); |
667 if($db->numrows() < 1) |
667 if($db->numrows() < 1) |
668 { |
668 { |
669 // This wasn't logged in <1.0.2, dunno how it slipped through |
669 // This wasn't logged in <1.0.2, dunno how it slipped through |
670 if($level > USER_LEVEL_MEMBER) |
670 if($level > USER_LEVEL_MEMBER) |
671 $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); |
671 $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); |
879 |
879 |
880 // Initialize our success switch |
880 // Initialize our success switch |
881 $success = false; |
881 $success = false; |
882 |
882 |
883 // Retrieve the real password from the database |
883 // Retrieve the real password from the database |
884 $this->sql('SELECT password,old_encryption,user_id,user_level,temp_password,temp_password_time FROM '.table_prefix.'users WHERE lcase(username)=\''.$this->prepare_text(strtolower($username)).'\';'); |
884 $this->sql('SELECT password,old_encryption,user_id,user_level,temp_password,temp_password_time FROM '.table_prefix.'users WHERE ' . ENANO_SQLFUNC_LOWERCASE . '(username)=\''.$this->prepare_text(strtolower($username)).'\';'); |
885 if($db->numrows() < 1) |
885 if($db->numrows() < 1) |
886 { |
886 { |
887 // This wasn't logged in <1.0.2, dunno how it slipped through |
887 // This wasn't logged in <1.0.2, dunno how it slipped through |
888 if($level > USER_LEVEL_MEMBER) |
888 if($level > USER_LEVEL_MEMBER) |
889 $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); |
889 $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); |
1207 . ' ON ( u.user_id=x.user_id OR x.user_id IS NULL )' . "\n" |
1207 . ' ON ( u.user_id=x.user_id OR x.user_id IS NULL )' . "\n" |
1208 . ' LEFT JOIN '.table_prefix.'privmsgs AS p' . "\n" |
1208 . ' LEFT JOIN '.table_prefix.'privmsgs AS p' . "\n" |
1209 . ' ON ( p.message_to=u.username AND p.message_read=0 )' . "\n" |
1209 . ' ON ( p.message_to=u.username AND p.message_read=0 )' . "\n" |
1210 . ' WHERE k.session_key=\''.$keyhash.'\'' . "\n" |
1210 . ' WHERE k.session_key=\''.$keyhash.'\'' . "\n" |
1211 . ' AND k.salt=\''.$salt.'\'' . "\n" |
1211 . ' AND k.salt=\''.$salt.'\'' . "\n" |
1212 . ' GROUP BY u.user_id;'); |
1212 . ' GROUP BY u.user_id,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level,x.user_id, x.user_aim, x.user_yahoo, x.user_msn, x.user_xmpp, x.user_homepage, x.user_location, x.user_job, x.user_hobbies, x.email_public;'); |
|
1213 |
1213 if ( !$query ) |
1214 if ( !$query ) |
1214 { |
1215 { |
1215 $query = $this->sql('SELECT u.user_id AS uid,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level,COUNT(p.message_id) AS num_pms FROM '.table_prefix.'session_keys AS k |
1216 $query = $this->sql('SELECT u.user_id AS uid,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level,COUNT(p.message_id) AS num_pms FROM '.table_prefix.'session_keys AS k |
1216 LEFT JOIN '.table_prefix.'users AS u |
1217 LEFT JOIN '.table_prefix.'users AS u |
1217 ON ( u.user_id=k.user_id ) |
1218 ON ( u.user_id=k.user_id ) |
1218 LEFT JOIN '.table_prefix.'privmsgs AS p |
1219 LEFT JOIN '.table_prefix.'privmsgs AS p |
1219 ON ( p.message_to=u.username AND p.message_read=0 ) |
1220 ON ( p.message_to=u.username AND p.message_read=0 ) |
1220 WHERE k.session_key=\''.$keyhash.'\' |
1221 WHERE k.session_key=\''.$keyhash.'\' |
1221 AND k.salt=\''.$salt.'\' |
1222 AND k.salt=\''.$salt.'\' |
1222 GROUP BY u.user_id;'); |
1223 GROUP BY u.user_id,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level;'); |
1223 } |
1224 } |
1224 if($db->numrows() < 1) |
1225 if($db->numrows() < 1) |
1225 { |
1226 { |
1226 // echo '(debug) $session->validate_session: Key was not found in database<br />'; |
1227 // echo '(debug) $session->validate_session: Key was not found in database<br />'; |
1227 return false; |
1228 return false; |
1570 $col_reason = ( $this->compat ) ? '"No reason entered (session manager is in compatibility mode)" AS reason' : 'reason'; |
1571 $col_reason = ( $this->compat ) ? '"No reason entered (session manager is in compatibility mode)" AS reason' : 'reason'; |
1571 $banned = false; |
1572 $banned = false; |
1572 if ( $this->user_logged_in ) |
1573 if ( $this->user_logged_in ) |
1573 { |
1574 { |
1574 // check by IP, email, and username |
1575 // check by IP, email, and username |
1575 $sql = "SELECT $col_reason, ban_value, ban_type, is_regex FROM " . table_prefix . "banlist WHERE \n" |
1576 if ( ENANO_DBLAYER == 'MYSQL' ) |
1576 . " ( ban_type = " . BAN_IP . " AND is_regex = 0 ) OR \n" |
1577 { |
1577 . " ( ban_type = " . BAN_IP . " AND is_regex = 1 AND '{$_SERVER['REMOTE_ADDR']}' REGEXP ban_value ) OR \n" |
1578 $sql = "SELECT $col_reason, ban_value, ban_type, is_regex FROM " . table_prefix . "banlist WHERE \n" |
1578 . " ( ban_type = " . BAN_USER . " AND is_regex = 0 AND ban_value = '{$this->username}' ) OR \n" |
1579 . " ( ban_type = " . BAN_IP . " AND is_regex = 0 ) OR \n" |
1579 . " ( ban_type = " . BAN_USER . " AND is_regex = 1 AND '{$this->username}' REGEXP ban_value ) OR \n" |
1580 . " ( ban_type = " . BAN_IP . " AND is_regex = 1 AND '{$_SERVER['REMOTE_ADDR']}' REGEXP ban_value ) OR \n" |
1580 . " ( ban_type = " . BAN_EMAIL . " AND is_regex = 0 AND ban_value = '{$this->email}' ) OR \n" |
1581 . " ( ban_type = " . BAN_USER . " AND is_regex = 0 AND ban_value = '{$this->username}' ) OR \n" |
1581 . " ( ban_type = " . BAN_EMAIL . " AND is_regex = 1 AND '{$this->email}' REGEXP ban_value ) \n" |
1582 . " ( ban_type = " . BAN_USER . " AND is_regex = 1 AND '{$this->username}' REGEXP ban_value ) OR \n" |
1582 . " ORDER BY ban_type ASC;"; |
1583 . " ( ban_type = " . BAN_EMAIL . " AND is_regex = 0 AND ban_value = '{$this->email}' ) OR \n" |
|
1584 . " ( ban_type = " . BAN_EMAIL . " AND is_regex = 1 AND '{$this->email}' REGEXP ban_value ) \n" |
|
1585 . " ORDER BY ban_type ASC;"; |
|
1586 } |
|
1587 else if ( ENANO_DBLAYER == 'PGSQL' ) |
|
1588 { |
|
1589 $sql = "SELECT $col_reason, ban_value, ban_type, is_regex FROM " . table_prefix . "banlist WHERE \n" |
|
1590 . " ( ban_type = " . BAN_IP . " AND is_regex = 0 ) OR \n" |
|
1591 . " ( ban_type = " . BAN_IP . " AND is_regex = 1 AND '{$_SERVER['REMOTE_ADDR']}' ~ ban_value ) OR \n" |
|
1592 . " ( ban_type = " . BAN_USER . " AND is_regex = 0 AND ban_value = '{$this->username}' ) OR \n" |
|
1593 . " ( ban_type = " . BAN_USER . " AND is_regex = 1 AND '{$this->username}' ~ ban_value ) OR \n" |
|
1594 . " ( ban_type = " . BAN_EMAIL . " AND is_regex = 0 AND ban_value = '{$this->email}' ) OR \n" |
|
1595 . " ( ban_type = " . BAN_EMAIL . " AND is_regex = 1 AND '{$this->email}' ~ ban_value ) \n" |
|
1596 . " ORDER BY ban_type ASC;"; |
|
1597 } |
1583 $q = $this->sql($sql); |
1598 $q = $this->sql($sql); |
1584 if ( $db->numrows() > 0 ) |
1599 if ( $db->numrows() > 0 ) |
1585 { |
1600 { |
1586 while ( list($reason, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) |
1601 while ( list($reason, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) |
1587 { |
1602 { |
1608 $db->free_result(); |
1623 $db->free_result(); |
1609 } |
1624 } |
1610 else |
1625 else |
1611 { |
1626 { |
1612 // check by IP only |
1627 // check by IP only |
1613 $sql = "SELECT $col_reason, ban_value, ban_type, is_regex FROM " . table_prefix . "banlist WHERE |
1628 if ( ENANO_DBLAYER == 'MYSQL' ) |
1614 ( ban_type = " . BAN_IP . " AND is_regex = 0 ) OR |
1629 { |
1615 ( ban_type = " . BAN_IP . " AND is_regex = 1 AND '{$_SERVER['REMOTE_ADDR']}' REGEXP ban_value ) |
1630 $sql = "SELECT $col_reason, ban_value, ban_type, is_regex FROM " . table_prefix . "banlist WHERE |
1616 ORDER BY ban_type ASC;"; |
1631 ( ban_type = " . BAN_IP . " AND is_regex = 0 ) OR |
|
1632 ( ban_type = " . BAN_IP . " AND is_regex = 1 AND '{$_SERVER['REMOTE_ADDR']}' REGEXP ban_value ) |
|
1633 ORDER BY ban_type ASC;"; |
|
1634 } |
|
1635 else if ( ENANO_DBLAYER == 'PGSQL' ) |
|
1636 { |
|
1637 $sql = "SELECT $col_reason, ban_value, ban_type, is_regex FROM " . table_prefix . "banlist WHERE |
|
1638 ( ban_type = " . BAN_IP . " AND is_regex = 0 ) OR |
|
1639 ( ban_type = " . BAN_IP . " AND is_regex = 1 AND '{$_SERVER['REMOTE_ADDR']}' ~ ban_value ) |
|
1640 ORDER BY ban_type ASC;"; |
|
1641 } |
1617 $q = $this->sql($sql); |
1642 $q = $this->sql($sql); |
1618 if ( $db->numrows() > 0 ) |
1643 if ( $db->numrows() > 0 ) |
1619 { |
1644 { |
1620 while ( list($reason, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) |
1645 while ( list($reason, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) |
1621 { |
1646 { |
1671 $username = $this->prepare_text($username); |
1696 $username = $this->prepare_text($username); |
1672 $email = $this->prepare_text($email); |
1697 $email = $this->prepare_text($email); |
1673 $real_name = $this->prepare_text($real_name); |
1698 $real_name = $this->prepare_text($real_name); |
1674 |
1699 |
1675 $nameclause = ( $real_name != '' ) ? ' OR real_name=\''.$real_name.'\'' : ''; |
1700 $nameclause = ( $real_name != '' ) ? ' OR real_name=\''.$real_name.'\'' : ''; |
1676 $q = $this->sql('SELECT * FROM '.table_prefix.'users WHERE lcase(username)=\''.strtolower($username).'\' OR email=\''.$email.'\''.$nameclause.';'); |
1701 $q = $this->sql('SELECT * FROM '.table_prefix.'users WHERE ' . ENANO_SQLFUNC_LOWERCASE . '(username)=\''.strtolower($username).'\' OR email=\''.$email.'\''.$nameclause.';'); |
1677 if($db->numrows() > 0) |
1702 if($db->numrows() > 0) |
1678 { |
1703 { |
1679 $r = 'The '; |
1704 $r = 'The '; |
1680 $i=0; |
1705 $i=0; |
1681 $row = $db->fetchrow(); |
1706 $row = $db->fetchrow(); |
2477 $q[] = '( target_type='.ACL_TYPE_GROUP.' AND target_id='.intval($g_id).' )'; |
2502 $q[] = '( target_type='.ACL_TYPE_GROUP.' AND target_id='.intval($g_id).' )'; |
2478 } |
2503 } |
2479 } |
2504 } |
2480 // The reason we're using an ORDER BY statement here is because ACL_TYPE_GROUP is less than ACL_TYPE_USER, causing the user's individual |
2505 // The reason we're using an ORDER BY statement here is because ACL_TYPE_GROUP is less than ACL_TYPE_USER, causing the user's individual |
2481 // permissions to override group permissions. |
2506 // permissions to override group permissions. |
2482 $bs .= implode(" OR\n ", $q) . " )\n AND (" . $pg_info . ' ( page_id=\''.$db->escape($paths->cpage['urlname_nons']).'\' AND namespace=\''.$db->escape($paths->namespace).'\' ) ) |
2507 $bs .= implode(" OR\n ", $q) . " )\n AND (" . $pg_info . ' ( page_id=\''.$db->escape($paths->page_id).'\' AND namespace=\''.$db->escape($paths->namespace).'\' ) ) |
2483 ORDER BY target_type ASC, page_id ASC, namespace ASC;'; |
2508 ORDER BY target_type ASC, page_id ASC, namespace ASC;'; |
2484 $q = $this->sql($bs); |
2509 $q = $this->sql($bs); |
2485 if ( $row = $db->fetchrow() ) |
2510 if ( $row = $db->fetchrow() ) |
2486 { |
2511 { |
2487 do { |
2512 do { |
2684 |
2709 |
2685 function make_captcha($len = 7) |
2710 function make_captcha($len = 7) |
2686 { |
2711 { |
2687 $code = $this->generate_captcha_code($len); |
2712 $code = $this->generate_captcha_code($len); |
2688 $hash = md5(microtime() . mt_rand()); |
2713 $hash = md5(microtime() . mt_rand()); |
2689 $this->sql('INSERT INTO '.table_prefix.'session_keys(session_key,salt,auth_level,source_ip,user_id) VALUES(\''.$hash.'\', \''.$s.'\', -1, \''.ip2hex($_SERVER['REMOTE_ADDR']).'\', -2);'); |
2714 $this->sql('INSERT INTO '.table_prefix.'session_keys(session_key,salt,auth_level,source_ip,user_id) VALUES(\''.$hash.'\', \'\', -1, \''.ip2hex($_SERVER['REMOTE_ADDR']).'\', -2);'); |
2690 return $hash; |
2715 return $hash; |
2691 } |
2716 } |
2692 |
2717 |
2693 /** |
2718 /** |
2694 * Generates the actual confirmation code text. |
2719 * Generates the actual confirmation code text. |