Changeset 42 for trunk/lib/Auth_SQL.inc.php
- Timestamp:
- Dec 18, 2005 12:16:03 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/Auth_SQL.inc.php
r41 r42 8 8 9 9 // Available encryption types for class Auth_SQL. 10 define('AUTH_ENCRYPT_MD5', 'md5'); 11 define('AUTH_ENCRYPT_CRYPT', 'crypt'); 12 define('AUTH_ENCRYPT_SHA1', 'sha1'); 13 define('AUTH_ENCRYPT_PLAINTEXT', 'plaintext'); 10 define('AUTH_ENCRYPT_MD5', 'md5'); 11 define('AUTH_ENCRYPT_CRYPT', 'crypt'); 12 define('AUTH_ENCRYPT_SHA1', 'sha1'); 13 define('AUTH_ENCRYPT_PLAINTEXT', 'plaintext'); 14 14 15 15 class Auth_SQL { … … 22 22 // Default param values. 23 23 var $_default_params = array( 24 24 25 25 // Message displayed by requireLogin(). 26 26 'login_required_message' => 'Please login', 27 27 28 28 // Automatically create table and verify columns. Better set to false after site launch. 29 29 'create_table' => true, 30 30 31 31 // The database table containing users to authenticate. 32 32 'db_table' => 'user_tbl', 33 33 34 34 // The name of the primary key for the db_table. 35 35 'db_primary_key' => 'user_id', 36 36 37 37 // The name of the username key for the db_table. 38 38 'db_username_column' => 'username', 39 39 40 40 // If using the db_login_table feature, specify the db_login_table. The primary key must match the primary key for the db_table. 41 41 'db_login_table' => 'user_login_tbl', 42 42 43 43 // The type of encryption to use for passwords stored in the db_table. Use one of the AUTH_ENCRYPT_* types specified above. 44 44 'encryption_type' => AUTH_ENCRYPT_MD5, … … 50 50 // This applies to admins and users. In seconds. 21600 seconds = 6 hours. 51 51 'login_timeout' => 21600, 52 52 53 53 // The maximum amount of time a user is allowed to be idle before their session expires. They will be forced to login again if they expire. 54 54 // This applies to admins and users. In seconds. 3600 seconds = 1 hour. … … 65 65 'login_abuse_max_ips' => 5, 66 66 67 // The IP address subnet size threshold. Uses a CIDR notation network mask (see CIDR cheatsheet at bottom). 68 // Any integar between 0 and 32 is permitted. Setting this to '24' permits any address in a 67 // The IP address subnet size threshold. Uses a CIDR notation network mask (see CIDR cheatsheet at bottom). 68 // Any integar between 0 and 32 is permitted. Setting this to '24' permits any address in a 69 69 // class C network (255.255.255.0) to be considered the same. Setting to '32' compares each IP absolutely. 70 70 // Setting to '0' ignores all IPs, thus disabling login_abuse checking. 71 71 'login_abuse_ip_bitmask' => 32, 72 72 73 // Specify usernames to exclude from the account abuse detection system. This is specified as a hardcoded array provided at 73 // Specify usernames to exclude from the account abuse detection system. This is specified as a hardcoded array provided at 74 74 // class instantiation time, or can be saved in the db_table under the login_abuse_exempt field. 75 75 'login_abuse_exempt_usernames' => array(), 76 76 77 77 // An array of IP blocks that are bypass the remote_addr comparison check. Useful for dynamic IPs or those behind proxy servers. 78 78 'trusted_networks' => array(), … … 80 80 // Allow user accounts to be blocked? Requires the user table to have the columns 'blocked' and 'blocked_reason' 81 81 'blocking' => false, 82 82 83 83 // Use a db_login_table to detect excessive logins. This requires blocking to be enabled. 84 84 'abuse_detection' => false, … … 106 106 } 107 107 } 108 108 109 109 /** 110 110 * Setup the database tables for this class. … … 117 117 { 118 118 static $_db_tested = false; 119 119 120 120 if ($recreate_db || !$_db_tested && $this->getParam('create_table')) { 121 121 122 122 // User table. 123 123 if ($recreate_db) { … … 154 154 155 155 if (!DB::columnExists($this->getParam('db_table'), array( 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 156 $this->getParam('db_primary_key'), 157 $this->getParam('db_username_column'), 158 'userpass', 159 'first_name', 160 'last_name', 161 'email', 162 'user_type', 163 'login_abuse_exempt', 164 'blocked', 165 'blocked_reason', 166 'abuse_warning_level', 167 'seconds_online', 168 'last_login_datetime', 169 'last_access_datetime', 170 'last_login_ip', 171 'added_by_user_id', 172 'modified_by_user_id', 173 'added_datetime', 174 'modified_datetime', 175 175 ), false, false)) { 176 176 App::logMsg(sprintf('Database table %s has invalid columns. Please update this table manually.', $this->getParam('db_table')), LOG_ALERT, __FILE__, __LINE__); 177 177 trigger_error(sprintf('Database table %s has invalid columns. Please update this table manually.', $this->getParam('db_table')), E_USER_ERROR); 178 178 } 179 179 180 180 // Login table is used for abuse_detection features. 181 181 if ($this->getParam('abuse_detection')) { … … 192 192 KEY remote_ip_binary (remote_ip_binary) 193 193 )"); 194 194 195 195 if (!DB::columnExists($this->getParam('db_login_table'), array( 196 196 $this->getParam('db_primary_key'), … … 202 202 } 203 203 } 204 } 204 } 205 205 $_db_tested = true; 206 206 } … … 239 239 } 240 240 } 241 241 242 242 /** 243 243 * Set the params of an auth object. … … 279 279 { 280 280 $this->initDB(); 281 281 282 282 DB::query(" 283 UPDATE " . $this->_params['db_table'] . " SET 283 UPDATE " . $this->_params['db_table'] . " SET 284 284 seconds_online = seconds_online + (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(last_access_datetime)), 285 285 last_login_datetime = '0000-00-00 00:00:00' … … 301 301 { 302 302 $this->initDB(); 303 303 304 304 // Query DB for user matching credentials. 305 305 $qid = DB::query(" 306 SELECT *, " . $this->_params['db_primary_key'] . " AS user_id 306 SELECT *, " . $this->_params['db_primary_key'] . " AS user_id 307 307 FROM " . $this->_params['db_table'] . " 308 308 WHERE " . $this->_params['db_username_column'] . " = '" . addslashes($username) . "' 309 309 AND BINARY userpass = '" . addslashes($this->encryptPassword($password)) . "' 310 310 "); 311 311 312 312 // Return user data if found. 313 313 if ($user_data = mysql_fetch_assoc($qid)) { … … 331 331 { 332 332 $this->initDB(); 333 333 334 334 $this->clearAuth(); 335 335 … … 351 351 'user_data' => $user_data 352 352 ); 353 353 354 354 /** 355 355 * Check if the account is blocked, respond in context to reason. Cancel the login if blocked. … … 357 357 if ($this->getParam('blocking')) { 358 358 if (!empty($user_data['blocked'])) { 359 359 360 360 App::logMsg(sprintf('%s %s (%s) login failed due to blocked account: %s', ucfirst($this->_auth), $this->getVal('user_id'), $this->getVal('username'), $this->getVal('blocked_reason')), LOG_NOTICE, __FILE__, __LINE__); 361 361 362 362 switch ($user_data['blocked_reason']) { 363 363 case 'account abuse' : … … 368 368 break; 369 369 } 370 370 371 371 // No login: user is blocked! 372 372 $this->clearAuth(); … … 374 374 } 375 375 } 376 376 377 377 /** 378 378 * Check the db_login_table for too many logins under this account. … … 412 412 DB::query(" 413 413 INSERT INTO " . $this->_params['db_login_table'] . " ( 414 " . $this->_params['db_primary_key'] . ", 415 login_datetime, 414 " . $this->_params['db_primary_key'] . ", 415 login_datetime, 416 416 remote_ip_binary 417 417 ) VALUES ( … … 422 422 "); 423 423 } 424 424 425 425 // Update user table with this login. 426 426 DB::query(" … … 431 431 WHERE " . $this->_params['db_primary_key'] . " = '" . $this->getVal('user_id') . "' 432 432 "); 433 433 434 434 // We're logged-in! 435 435 return true; … … 449 449 { 450 450 $this->initDB(); 451 451 452 452 if (isset($user_id)) { 453 453 // Check the login status of a specific user. … … 465 465 return $_SESSION[$this->_sess]['authenticated']; 466 466 } 467 467 468 468 // Tesing login should occur once. This is the first time. Set flag. 469 469 $this->_authentication_tested = true; … … 472 472 if ($trusted_net = ipInRange(getRemoteAddr(), $this->_params['trusted_networks'])) { 473 473 $user_in_trusted_network = true; 474 App::logMsg(sprintf('%s%s accessing from trusted network %s', 475 ucfirst($this->_auth), 474 App::logMsg(sprintf('%s%s accessing from trusted network %s', 475 ucfirst($this->_auth), 476 476 ($this->getVal('user_id') ? ' ' . $this->getVal('user_id') . ' (' . $this->getVal('username') . ')' : ''), 477 477 $trusted_net … … 479 479 } else if (preg_match('/proxy.aol.com$/i', getRemoteAddr(true))) { 480 480 $user_in_trusted_network = true; 481 App::logMsg(sprintf('%s%s accessing from trusted network proxy.aol.com', 482 ucfirst($this->_auth), 481 App::logMsg(sprintf('%s%s accessing from trusted network proxy.aol.com', 482 ucfirst($this->_auth), 483 483 ($this->getVal('user_id') ? ' ' . $this->getVal('user_id') . ' (' . $this->getVal('username') . ')' : '') 484 484 ), LOG_INFO, __FILE__, __LINE__); … … 486 486 $user_in_trusted_network = false; 487 487 } 488 488 489 489 // Test login with information stored in session. Skip IP matching for users from trusted networks. 490 490 if (isset($_SESSION[$this->_sess]) … … 500 500 // Update the DB with the last_access_datetime and increment the seconds_online. 501 501 DB::query(" 502 UPDATE " . $this->_params['db_table'] . " SET 502 UPDATE " . $this->_params['db_table'] . " SET 503 503 seconds_online = seconds_online + (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(last_access_datetime)) + 1, 504 504 last_access_datetime = '" . $this->getVal('last_access_datetime') . "' … … 517 517 App::raiseMsg(sprintf(_("Your %s session has closed. You need to log-in again."), strtolower($this->_auth)), MSG_NOTICE, __FILE__, __LINE__); 518 518 } 519 519 520 520 // Log the reason for login expiration. 521 521 $expire_reasons = array(); … … 565 565 * This sets the 'blocked' field for a user in the db_table, and also 566 566 * adds an optional reason 567 * 567 * 568 568 * @param string $reason The reason for blocking the account. 569 569 */ … … 571 571 { 572 572 $this->initDB(); 573 573 574 574 if ($this->getParam('blocking')) { 575 575 if (strlen(addslashes($reason)) > 255) { … … 577 577 App::logMsg(sprintf('Blocked reason provided is greater than 255 characters: %s', $reason), LOG_WARNING, __FILE__, __LINE__); 578 578 } 579 579 580 580 // Get user_id if specified. 581 581 $user_id = isset($user_id) ? $user_id : $this->getVal('user_id'); … … 590 590 591 591 /** 592 * Unblocks a user in the db_table, and clears any blocked_reason. 592 * Unblocks a user in the db_table, and clears any blocked_reason. 593 593 */ 594 594 function unblockAccount($user_id=null) 595 595 { 596 596 $this->initDB(); 597 597 598 598 if ($this->getParam('blocking')) { 599 599 // Get user_id if specified. … … 615 615 */ 616 616 function usernameExists($username) 617 { 618 $this->initDB(); 619 617 { 618 $this->initDB(); 619 620 620 $qid = DB::query(" 621 SELECT 1 621 SELECT 1 622 622 FROM " . $this->_params['db_table'] . " 623 623 WHERE " . $this->_params['db_username_column'] . " = '" . addslashes($username) . "' … … 633 633 */ 634 634 function getUsername($user_id) 635 { 636 $this->initDB(); 637 635 { 636 $this->initDB(); 637 638 638 $qid = DB::query(" 639 639 SELECT " . $this->_params['db_username_column'] . " … … 679 679 return $str; 680 680 } 681 681 682 682 /** 683 683 * … … 689 689 return $password; 690 690 break; 691 691 692 692 case AUTH_ENCRYPT_CRYPT : 693 693 return crypt($password, crypt($password)); 694 694 break; 695 695 696 696 case AUTH_ENCRYPT_SHA1 : 697 697 return sha1($password); 698 698 break; 699 699 700 700 case AUTH_ENCRYPT_MD5 : 701 701 default : … … 706 706 707 707 /** 708 * 708 * 709 709 */ 710 710 function setPassword($user_id=null, $password) 711 { 712 $this->initDB(); 713 711 { 712 $this->initDB(); 713 714 714 // Get user_id if specified. 715 715 $user_id = isset($user_id) ? $user_id : $this->getVal('user_id'); 716 716 717 717 // Issue the password change query. 718 718 DB::query(" 719 UPDATE " . $this->_params['db_table'] . " 719 UPDATE " . $this->_params['db_table'] . " 720 720 SET userpass = '" . addslashes($this->encryptPassword($password)) . "' 721 721 WHERE " . $this->_params['db_primary_key'] . " = '" . addslashes($user_id) . "' … … 733 733 { 734 734 $this->initDB(); 735 735 736 736 // Get user_id if specified. 737 737 $user_id = isset($user_id) ? $user_id : $this->getVal('user_id'); 738 738 739 739 // Reset password of a specific user. 740 740 $qid = DB::query(" … … 746 746 return false; 747 747 } 748 748 749 749 // Make sure user has an email on record. 750 750 if (!isset($user_data['email']) || '' == trim($user_data['email'])) { … … 754 754 // Get new password. 755 755 $password = $this->generatePassword(); 756 756 757 757 // Update password query. 758 758 $this->setPassword($user_id, $password); … … 791 791 )); 792 792 $email->send(); 793 793 794 794 return array( 795 'username' => $user_data[$this->_params['db_username_column']], 795 'username' => $user_data[$this->_params['db_username_column']], 796 796 'userpass' => $password 797 797 ); 798 798 } 799 799 800 800 /** 801 801 * If the current user has access to the specified $security_zone, return true. 802 * If the optional $priv is supplied, test that against the zone. 802 * If the optional $priv is supplied, test that against the zone. 803 803 * 804 804 * @param constant $security_zone string of comma delimited priviliges for the zone … … 811 811 $zone_members = preg_split('/,\s*/', $security_zone); 812 812 $priv = empty($priv) ? $this->getVal('priv') : $priv; 813 814 // If the current user's privilege level is NOT in that array or if the 813 814 // If the current user's privilege level is NOT in that array or if the 815 815 // user has no privilege, return false. Otherwise the user is clear. 816 816 if (!in_array($priv, $zone_members) || empty($priv)) { … … 820 820 } 821 821 } 822 822 823 823 /** 824 824 * This function tests a list of arguments $security_zone against the priv that the current user has. 825 * If the user doesn't have one of the supplied privs, die. 825 * If the user doesn't have one of the supplied privs, die. 826 826 * 827 827 * @param constant $security_zone string of comma delimited priviliges for the zone … … 831 831 return true; 832 832 $zone_members = preg_split('/,\s*/', $security_zone); 833 834 /* If the current user's privilege level is NOT in that array or if the 833 834 /* If the current user's privilege level is NOT in that array or if the 835 835 * user has no privilege, DIE with a message. */ 836 836 if (!in_array($this->getVal('priv'), $zone_members) || !$this->getVal('priv')) { … … 845 845 // CIDR cheatsheet 846 846 // 847 // Netmask Netmask (binary) CIDR Notes 847 // Netmask Netmask (binary) CIDR Notes 848 848 // _____________________________________________________________________________ 849 849 // 255.255.255.255 11111111.11111111.11111111.11111111 /32 Host (single addr) … … 856 856 // 255.255.255.128 11111111.11111111.11111111.10000000 /25 126 useable 857 857 // 255.255.255.0 11111111.11111111.11111111.00000000 /24 "Class C" 254 useable 858 // 858 // 859 859 // 255.255.254.0 11111111.11111111.11111110.00000000 /23 2 Class C's 860 860 // 255.255.252.0 11111111.11111111.11111100.00000000 /22 4 Class C's … … 865 865 // 255.255.128.0 11111111.11111111.10000000.00000000 /17 128 Class C's 866 866 // 255.255.0.0 11111111.11111111.00000000.00000000 /16 "Class B" 867 // 867 // 868 868 // 255.254.0.0 11111111.11111110.00000000.00000000 /15 2 Class B's 869 869 // 255.252.0.0 11111111.11111100.00000000.00000000 /14 4 Class B's … … 874 874 // 255.128.0.0 11111111.10000000.00000000.00000000 /9 128 Class B's 875 875 // 255.0.0.0 11111111.00000000.00000000.00000000 /8 "Class A" 876 // 876 // 877 877 // 254.0.0.0 11111110.00000000.00000000.00000000 /7 878 878 // 252.0.0.0 11111100.00000000.00000000.00000000 /6
Note: See TracChangeset
for help on using the changeset viewer.