Changeset 500
- Timestamp:
- Nov 15, 2014 9:34:39 PM (9 years ago)
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
tags/2.1.8/lib/Currency.inc.php
r484 r500 4 4 * For details visit the project site: <http://trac.strangecode.com/codebase/> 5 5 * Copyright 2001-2012 Strangecode, LLC 6 * 6 * 7 7 * This file is part of The Strangecode Codebase. 8 8 * … … 11 11 * Free Software Foundation, either version 3 of the License, or (at your option) 12 12 * any later version. 13 * 13 * 14 14 * The Strangecode Codebase is distributed in the hope that it will be useful, but 15 15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 17 17 * details. 18 * 18 * 19 19 * You should have received a copy of the GNU General Public License along with 20 20 * The Strangecode Codebase. If not, see <http://www.gnu.org/licenses/>. … … 28 28 * @author Quinn Comendant <quinn@strangecode.com> 29 29 * @version 1.5 30 * 30 * 31 31 * Example of use: 32 32 --------------------------------------------------------------------- … … 37 37 --------------------------------------------------------------------- 38 38 */ 39 39 40 40 class Currency { 41 41 … … 48 48 'api_key' => '', // Used only by xurrency API. 49 49 ); 50 50 51 51 /** 52 52 * Cart constructor. … … 58 58 // Set custom parameters. 59 59 $this->setParam($params); 60 60 61 61 // Setup cache directory. 62 62 if ($this->getParam('cache_result')) { … … 66 66 } 67 67 if (!is_dir($this->getParam('cache_dir'))) { 68 $app->logMsg(sprintf('Creating cache_dir: %s', $this->getParam('cache_dir')), LOG_INFO, __FILE__, __LINE__); 68 $app->logMsg(sprintf('Creating cache_dir: %s', $this->getParam('cache_dir')), LOG_INFO, __FILE__, __LINE__); 69 69 if (!mkdir($this->getParam('cache_dir'))) { 70 $app->logMsg(sprintf('Could not create cache_dir: %s', $this->getParam('cache_dir')), LOG_WARNING, __FILE__, __LINE__); 70 $app->logMsg(sprintf('Could not create cache_dir: %s', $this->getParam('cache_dir')), LOG_WARNING, __FILE__, __LINE__); 71 71 } 72 72 } … … 97 97 { 98 98 $app =& App::getInstance(); 99 99 100 100 if (array_key_exists($param, $this->_params)) { 101 101 return $this->_params[$param]; … … 105 105 } 106 106 } 107 107 108 108 /* 109 109 * Return the exchange value between the two given currencies for given amount. … … 113 113 * @param string $base 3-letter currency code to convert from. 114 114 * @param string $target 3-letter currency code to convert to. 115 * @return mixed Float converted currency value, or false on error. 115 * @return mixed Float converted currency value, or false on error. 116 116 * @author Quinn Comendant <quinn@strangecode.com> 117 117 * @version 1.0 … … 121 121 { 122 122 if (false !== $rate = $this->getRate($base, $target)) { 123 return abs($rate * $amount); 123 return abs($rate * $amount); 124 124 } else { 125 125 return false; 126 126 } 127 127 } 128 128 129 129 /* 130 130 * Return the currency conversion rate as a ratio. … … 133 133 * @param string $base 3-letter currency code to convert from. 134 134 * @param string $target 3-letter currency code to convert to. 135 * @return mixed Float exchange rate value, or false on error. 135 * @return mixed Float exchange rate value, or false on error. 136 136 * @author Quinn Comendant <quinn@strangecode.com> 137 137 * @version 1.0 … … 173 173 return trim($value); 174 174 } 175 175 176 176 /** 177 177 * @param string … … 215 215 $api_url = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'; 216 216 if (false === $sXML = file_get_contents($api_url)) { 217 $app->logMsg(sprintf('Failed to load ECB XML data from 217 $app->logMsg(sprintf('Failed to load ECB XML data from: %s', $api_url), LOG_WARNING, __FILE__, __LINE__); 218 218 return false; 219 219 } 220 220 if (false === $oXML = simplexml_load_string($sXML)) { 221 $app->logMsg(sprintf('Failed to decode ECB XML data: ', truncate($sXML, 200, 'end')), LOG_WARNING, __FILE__, __LINE__);221 $app->logMsg(sprintf('Failed to decode ECB XML data: %s', truncate($sXML, 200, 'end')), LOG_WARNING, __FILE__, __LINE__); 222 222 return false; 223 223 } -
trunk/bin/module_maker/_config.inc.php
r468 r500 35 35 36 36 // Make sure necessary files exist. 37 if (!file_exists(COMMON_BASE . '/global/db_auth.inc.php')) { 37 $db_auth_file = false; 38 $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(COMMON_BASE)); 39 $rii->setMaxDepth(2); 40 foreach ($rii as $filename => $file) { 41 if (mb_strpos($filename, 'db_auth.inc.php') !== false) { 42 $db_auth_file = $filename; 43 break; 44 } 45 } 46 47 if (!$db_auth_file) { 38 48 die("Error: First argument directory must contain the global/db_auth.inc.php file with valid MySQL credentials.\n"); 39 49 } … … 63 73 'log_screen_priority' => LOG_DEBUG, 64 74 )); 65 require_once 'global/db_auth.inc.php';75 require_once $db_auth_file; 66 76 67 77 // Start application-based functionality: database, session, environment, ini setup, etc. -
trunk/bin/module_maker/module.cli.php
r468 r500 5 5 * For details visit the project site: <http://trac.strangecode.com/codebase/> 6 6 * Copyright 2001-2012 Strangecode, LLC 7 * 7 * 8 8 * This file is part of The Strangecode Codebase. 9 9 * … … 12 12 * Free Software Foundation, either version 3 of the License, or (at your option) 13 13 * any later version. 14 * 14 * 15 15 * The Strangecode Codebase is distributed in the hope that it will be useful, but 16 16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 18 18 * details. 19 * 19 * 20 20 * You should have received a copy of the GNU General Public License along with 21 21 * The Strangecode Codebase. If not, see <http://www.gnu.org/licenses/>. … … 39 39 40 40 " . basename($_SERVER['argv'][0]) . " site_directory name_singular name_plural [operation] 41 41 42 42 Valid operations include: " . join(', ', $valid_ops) . " 43 43 … … 149 149 if (!is_dir("$public_tpl_dir")) { 150 150 die(basename($_SERVER['argv'][0]) . " Error: public_tpl_dir '$public_tpl_dir' directory not found.\n"); 151 } 151 } 152 152 } 153 153 … … 196 196 $type = preg_replace('/^(\w+).*$/', '\\1', $col[1]); 197 197 $default = $col[4]; 198 198 199 199 if (mb_strpos($default, '0000') !== false || '0' == $default) { 200 200 $default = ''; -
trunk/bin/module_maker/skel/admin.php
r479 r500 408 408 "; 409 409 410 // Use a ca shhash to determine if the result-set has changed.410 // Use a cache hash to determine if the result-set has changed. 411 411 // A unique key for this query, with the total_items in case db records 412 412 // were added since the last cache. This identifies a unique set of -
trunk/css/admin2.inc.css
r493 r500 392 392 width: auto; 393 393 } 394 395 /* Hide foundation elements for sites still using old admin css. */ 396 .sc-msg .close { 397 display: none; 398 } -
trunk/js/Msg.js
r497 r500 48 48 // Merge options with defaults 49 49 this.o = $.extend({ 50 container: '#sc-msg ',50 container: '#sc-msg:last', 51 51 above_msg: '', 52 52 gotohash: true … … 74 74 if (!$(this.o.container).find(':contains("' + message + '")').length) { 75 75 $(this.o.container).append($('<div class="sc-js-msg ' + msg_class + '"></div>').text(message)).show(); 76 // $(this.o.container).append($('<div data-alert class="alert-box sc-js-msg ' + msg_class + '"></div>').hide().text(message).append('<a href="#" class="close">Ã</a>')); 77 // $('.sc-js-msg').slideDown('fast'); 76 78 } 77 79 -
trunk/js/Utilities.js
r497 r500 41 41 var args = arguments; 42 42 return this.replace(/{(\d+)}/g, function(match, number) { 43 return typeof args[number ] != 'undefined' ? args[number] : match;43 return typeof args[number-1] != 'undefined' ? args[number-1] : match; 44 44 }); 45 45 }; -
trunk/lib/App.inc.php
r499 r500 80 80 'ssl_enabled' => false, 81 81 82 // Use CSRF tokens. 83 'csrf_token_enabled' => true, 84 'csrf_token_name' => 'csrf_token', 85 'csrf_token_timeout' => 86400, // In seconds. This causes form tokens to be unusable after this duration. This might only cause problems when opening forms in multiple tabs left open beyond the timeout duration. But usually their session will timeout first, and they'll receive new tokens when they load the form again.. 86 87 // HMAC signing method 88 'signing_method' => 'sha512+base64', 89 82 90 // Character set for page output. Used in the Content-Type header and the HTML <meta content-type> tag. 83 91 'character_set' => 'utf-8', … … 450 458 451 459 if ('' == trim($message)) { 452 $this->logMsg(sprintf('Raised message is an empty string.', __FUNCTION__), LOG_NOTICE, __FILE__, __LINE__);460 $this->logMsg(sprintf('Raised message is an empty string.', null), LOG_NOTICE, __FILE__, __LINE__); 453 461 return false; 454 462 } … … 944 952 } 945 953 946 /*947 * Return a URL with a version number attached. This is useful for overriding network caches ("cache buster") for sourced media, e.g., /style.css?812763482948 *949 * @access public950 * @param string $url URL to media (e.g., /foo.js)951 * @return string URL with cache-busting version appended (/foo.js?v=1234567890)952 * @author Quinn Comendant <quinn@strangecode.com>953 * @version 1.0954 * @since 03 Sep 2014 22:40:24955 */956 public function cacheBustURL($url)957 {958 // Get the first delimiter that is needed in the url.959 $delim = mb_strpos($url, '?') !== false ? ini_get('arg_separator.output') : '?';960 $v = crc32($this->getParam('codebase_version') . '|' . $this->getParam('site_version'));961 return sprintf('%s%sv=%s', $url, $delim, $v);962 }963 964 954 /** 965 955 * Prints a hidden form element with the PHPSESSID when cookies are not used, as well … … 971 961 * array('key1'=>'value', key2'='value') <-- to set keys to default values if not present in form data. 972 962 * false <-- To not carry any queries. If URL already has queries those will be retained. 973 */ 974 public function printHiddenSession($carry_args=null) 963 * @param bool $include_csrf_token Set to true to include the csrf_token in the form. Only use this for forms with action="post" to prevent the token from being revealed in the URL. 964 */ 965 public function printHiddenSession($carry_args=null, $include_csrf_token=false) 975 966 { 976 967 if (!$this->running) { … … 1023 1014 printf('<input type="hidden" name="%s" value="%s" />', session_name(), session_id()); 1024 1015 } 1016 1017 // Include the csrf_token in the form. 1018 // This token can be validated upon form submission with $app->verifyCSRFToken() or $app->requireValidCSRFToken() 1019 if ($this->getParam('csrf_token_enabled') && $include_csrf_token) { 1020 printf('<input type="hidden" name="%s" value="%s" />', $this->getParam('csrf_token_name'), $this->recycleCSRFToken()); 1021 } 1022 } 1023 1024 /* 1025 * Return a URL with a version number attached. This is useful for overriding network caches ("cache buster") for sourced media, e.g., /style.css?812763482 1026 * 1027 * @access public 1028 * @param string $url URL to media (e.g., /foo.js) 1029 * @return string URL with cache-busting version appended (/foo.js?v=1234567890) 1030 * @author Quinn Comendant <quinn@strangecode.com> 1031 * @version 1.0 1032 * @since 03 Sep 2014 22:40:24 1033 */ 1034 public function cacheBustURL($url) 1035 { 1036 // Get the first delimiter that is needed in the url. 1037 $delim = mb_strpos($url, '?') !== false ? ini_get('arg_separator.output') : '?'; 1038 $v = crc32($this->getParam('codebase_version') . '|' . $this->getParam('site_version')); 1039 return sprintf('%s%sv=%s', $url, $delim, $v); 1040 } 1041 1042 /* 1043 * Generate a csrf_token, saving it to the session and returning its value. 1044 * https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#General_Recommendation:_Synchronizer_Token_Pattern 1045 * @access public 1046 * @return string The new csrf_token. 1047 * @author Quinn Comendant <quinn@strangecode.com> 1048 * @version 1.0 1049 * @since 15 Nov 2014 17:53:51 1050 */ 1051 public function generateCSRFToken() 1052 { 1053 return $_SESSION['_app'][$this->_ns]['csrf_tokens'][] = addSignature(time(), null, 64); 1054 } 1055 1056 /* 1057 * Update the csrf_token to a new value if it hasn't been set yet or has expired. 1058 * Save the previous csrf_token in the session to ensure continuity of currently open sessions. 1059 * 1060 * @access public 1061 * @return string The current csrf_token 1062 * @author Quinn Comendant <quinn@strangecode.com> 1063 * @version 1.0 1064 * @since 15 Nov 2014 17:57:17 1065 */ 1066 public function recycleCSRFToken() 1067 { 1068 if (!isset($_SESSION['_app'][$this->_ns]['csrf_tokens'])) { 1069 // No token yet; generate one and return it. 1070 $_SESSION['_app'][$this->_ns]['csrf_tokens'] = array(); 1071 $return = $this->generateCSRFToken(); 1072 } 1073 if (removeSignature(end($_SESSION['_app'][$this->_ns]['csrf_tokens'])) + $this->getParam('csrf_token_timeout') < time()) { 1074 // Newest token is expired; prune array of tokens and generate new token. 1075 // We'll save the 10-most-recent tokens. This allows the user to submit up to 5 forms saved in previously opened tabs with expired tokens (loading a form will prune one token, and submitting a form will prune one token, thus 10 = 5). 1076 $_SESSION['_app'][$this->_ns]['csrf_tokens'] = array_slice($_SESSION['_app'][$this->_ns]['csrf_tokens'], -10, 10); 1077 $return = $this->generateCSRFToken(); 1078 } 1079 // Current token is not expired; return it. 1080 $return = end($_SESSION['_app'][$this->_ns]['csrf_tokens']); 1081 $app =& App::getInstance(); 1082 return $return; 1083 } 1084 1085 /* 1086 * Compares the given csrf_token with the current or previous one saved in the session. 1087 * 1088 * @access public 1089 * @param string $csrf_token The token to compare with the session token. 1090 * @return bool True if the tokens match, false otherwise. 1091 * @author Quinn Comendant <quinn@strangecode.com> 1092 * @version 1.0 1093 * @since 15 Nov 2014 18:06:55 1094 */ 1095 public function verifyCSRFToken($csrf_token) 1096 { 1097 $app =& App::getInstance(); 1098 1099 if (!$this->getParam('csrf_token_enabled')) { 1100 $app->logMsg(sprintf('%s method called, but csrf_token_enabled=false', __FUNCTION__), LOG_ERR, __FILE__, __LINE__); 1101 return false; 1102 } 1103 if ('' == trim($csrf_token)) { 1104 $app->logMsg(sprintf('Empty string failed CSRF verification.', null), LOG_NOTICE, __FILE__, __LINE__); 1105 return false; 1106 } 1107 if (!verifySignature($csrf_token, null, 64)) { 1108 $app->logMsg(sprintf('Input failed CSRF verification (invalid signature in %s).', $csrf_token), LOG_WARNING, __FILE__, __LINE__); 1109 return false; 1110 } 1111 $this->recycleCSRFToken(); 1112 if (!in_array($csrf_token, $_SESSION['_app'][$this->_ns]['csrf_tokens'])) { 1113 $app->logMsg(sprintf('Input failed CSRF verification (%s not in %s).', $csrf_token, getDump($_SESSION['_app'][$this->_ns]['csrf_tokens'])), LOG_WARNING, __FILE__, __LINE__); 1114 return false; 1115 } 1116 // $app->logMsg(sprintf('Verified token %s is in %s', $csrf_token, getDump($_SESSION['_app'][$this->_ns]['csrf_tokens'])), LOG_DEBUG, __FILE__, __LINE__); 1117 return true; 1118 } 1119 1120 /* 1121 * Bounce user if they submit a token that doesn't match the one saved in the session. 1122 * Because this function calls dieURL() it must be called before any other HTTP header output. 1123 * 1124 * @access public 1125 * @param string $csrf_token The token to compare with the session token. 1126 * @param string $message Optional message to display to the user (otherwise default message will display). Set to an empty string to display no message. 1127 * @param int $type The type of message: MSG_NOTICE, 1128 * MSG_SUCCESS, MSG_WARNING, or MSG_ERR. 1129 * @param string $file __FILE__. 1130 * @param string $line __LINE__. 1131 * @return void 1132 * @author Quinn Comendant <quinn@strangecode.com> 1133 * @version 1.0 1134 * @since 15 Nov 2014 18:10:17 1135 */ 1136 public function requireValidCSRFToken($csrf_token, $message=null, $type=MSG_NOTICE, $file=null, $line=null) 1137 { 1138 $app =& App::getInstance(); 1139 1140 if (!$this->verifyCSRFToken($csrf_token)) { 1141 $message = isset($message) ? $message : _("Something went wrong; please try again."); 1142 $app->raiseMsg($message, $type, $file, $line); 1143 $app->dieBoomerangURL(); 1144 } 1025 1145 } 1026 1146 -
trunk/lib/Auth_SQL.inc.php
r497 r500 39 39 const ENCRYPT_MD5 = 5; 40 40 const ENCRYPT_MD5_HARDENED = 6; 41 const ENCRYPT_PASSWORD_BCRYPT = 7; 42 const ENCRYPT_PASSWORD_DEFAULT = 8; 41 43 42 44 // Namespace of this auth object. … … 174 176 " . $this->getParam('db_username_column') . " varchar(255) NOT NULL default '', 175 177 userpass VARCHAR(255) NOT NULL DEFAULT '', 178 userpass_hashtype TINYINT UNSIGNED NOT NULL DEFAULT '0', 176 179 first_name VARCHAR(255) NOT NULL DEFAULT '', 177 180 last_name VARCHAR(255) NOT NULL DEFAULT '', … … 260 263 $params['login_abuse_exempt_usernames'] = array_map('strtolower', $params['login_abuse_exempt_usernames']); 261 264 } 265 if (isset($params['encryption_type']) && version_compare(PHP_VERSION, '5.5.0', '<') && in_array($params['encryption_type'], array(self::ENCRYPT_PASSWORD_BCRYPT, self::ENCRYPT_PASSWORD_DEFAULT))) { 266 // These hash types require the password_* userland lib in PHP < 5.5.0 267 $pw_compat_lib = 'vendor/ircmaxell/password-compat/lib/password.php'; 268 if (false !== stream_resolve_include_path($pw_compat_lib)) { 269 include_once $pw_compat_lib; 270 } else { 271 $app =& App::getInstance(); 272 $app->logMsg(sprintf('Encryption type %s requires password-compat lib in PHP < 5.5.0; falling back to ENCRYPT_SHA1', $params['encryption_type']), LOG_ERR, __FILE__, __LINE__); 273 $params['encryption_type'] = self::ENCRYPT_SHA1; 274 } 275 } 262 276 if (isset($params) && is_array($params)) { 263 277 // Merge new parameters with old overriding only those passed. … … 353 367 354 368 /** 355 * Find out if a set of login credentials are valid.369 * Retrieve and verify the given username and password against a matching user record in the database. 356 370 * 357 371 * @access private … … 367 381 $this->initDB(); 368 382 369 switch ($this->_params['encryption_type']) { 370 case self::ENCRYPT_CRYPT : 371 // Query DB for user matching credentials. Compare cyphertext with salted-encrypted password. 372 $qid = $db->query(" 373 SELECT *, " . $this->_params['db_primary_key'] . " AS user_id 374 FROM " . $this->_params['db_table'] . " 375 WHERE " . $this->_params['db_username_column'] . " = '" . $db->escapeString($username) . "' 376 AND BINARY userpass = ENCRYPT('" . $db->escapeString($password) . "', LEFT(userpass, 2))) 377 "); 378 break; 379 case self::ENCRYPT_PLAINTEXT : 380 case self::ENCRYPT_MD5 : 381 case self::ENCRYPT_SHA1 : 382 default : 383 // Query DB for user matching credentials. Directly compare cyphertext with result from encryptPassword(). 384 $qid = $db->query(" 385 SELECT *, " . $this->_params['db_primary_key'] . " AS user_id 386 FROM " . $this->_params['db_table'] . " 387 WHERE " . $this->_params['db_username_column'] . " = '" . $db->escapeString($username) . "' 388 AND BINARY userpass = '" . $db->escapeString($this->encryptPassword($password)) . "' 389 "); 390 break; 391 } 392 393 // Return user data if found. 394 if ($user_data = mysql_fetch_assoc($qid)) { 395 // Don't return password value. 396 unset($user_data['userpass']); 397 $app->logMsg(sprintf('Authentication successful for user_id %s (%s)', $user_data['user_id'], $username), LOG_INFO, __FILE__, __LINE__); 383 // Get user data for specified username. 384 // Query DB for user matching credentials. Compare cyphertext with salted-encrypted password. 385 $qid = $db->query(" 386 SELECT *, " . $this->_params['db_primary_key'] . " AS user_id 387 FROM " . $this->_params['db_table'] . " 388 WHERE " . $this->_params['db_username_column'] . " = '" . $db->escapeString($username) . "' 389 "); 390 if (!$user_data = mysql_fetch_assoc($qid)) { 391 $app->logMsg(sprintf('Username %s not found for authentication', $username), LOG_NOTICE, __FILE__, __LINE__); 392 return false; 393 } 394 395 if ($this->verifyPassword($password, $user_data['userpass'])) { 396 $app->logMsg(sprintf('Authentication successful for %s (user_id=%s)', $username, $user_data['user_id']), LOG_INFO, __FILE__, __LINE__); 397 unset($user_data['userpass']); // Avoid revealing the encrypted password in the $user_data. 398 398 return $user_data; 399 } else {400 $app->logMsg(sprintf('Authentication failed for username %s (encrypted attempted password: %s)', $username, $this->encryptPassword($password)), LOG_NOTICE, __FILE__, __LINE__); 401 return false;402 }399 } 400 401 $app->logMsg(sprintf('Authentication failed for %s (user_id=%s)', $username, $user_data['user_id']), LOG_NOTICE, __FILE__, __LINE__); 402 return false; 403 403 } 404 404 … … 553 553 SELECT 1 FROM " . $this->_params['db_table'] . " 554 554 WHERE " . $this->_params['db_primary_key'] . " = '" . $db->escapeString($user_id) . "' 555 AND DATE_ADD(last_login_datetime, INTERVAL '" . $this->_params['login_timeout'] . "' SECOND) > NOW()556 AND DATE_ADD(last_access_datetime, INTERVAL '" . $this->_params['idle_timeout'] . "' SECOND) > NOW()555 AND last_login_datetime > DATE_SUB(NOW(), INTERVAL '" . $this->_params['login_timeout'] . "' SECOND) 556 AND last_access_datetime > DATE_SUB(NOW(), INTERVAL '" . $this->_params['idle_timeout'] . "' SECOND) 557 557 "); 558 558 $login_status = (mysql_num_rows($qid) > 0); … … 809 809 } 810 810 811 /** 812 * Returns a randomly generated password based on $pattern. The pattern is any 813 * sequence of 'x', 'V', 'C', 'v', 'c', or 'd' and if it is something like 'cvccv' this 814 * function will generate a pronounceable password. Recommend using more complex 815 * patterns, at minimum the US State Department standard: cvcddcvc. 816 * 817 * - x A random upper or lower character, digit, or punctuation. 818 * - C A random upper or lower consonant. 819 * - V A random upper or lower vowel. 820 * - c A random lowercase consonant. 821 * - v A random lowercase vowel. 822 * - d A random digit. 823 * 824 * @param string $pattern a sequence of character types, above. 825 * @return string a password 826 */ 827 public function generatePassword($pattern='CvcdCvc') 828 { 829 $app =& App::getInstance(); 830 if (preg_match('/[^xCVcvd]/', $pattern)) { 831 $app->logMsg(sprintf('Invalid pattern: %s', $pattern), LOG_WARNING, __FILE__, __LINE__); 832 $pattern='CvcdCvc'; 833 } 834 $str = ''; 835 for ($i=0; $i<mb_strlen($pattern); $i++) { 836 $x = mb_substr('bcdfghjklmnprstvwxzBCDFGHJKLMNPRSTVWXZaeiouyAEIOUY0123456789!@#%&*-=+.?', (mt_rand() % 71), 1); 837 $c = mb_substr('bcdfghjklmnprstvwxz', (mt_rand() % 19), 1); 838 $C = mb_substr('bcdfghjklmnprstvwxzBCDFGHJKLMNPRSTVWXZ', (mt_rand() % 38), 1); 839 $v = mb_substr('aeiouy', (mt_rand() % 6), 1); 840 $V = mb_substr('aeiouyAEIOUY', (mt_rand() % 12), 1); 841 $d = mb_substr('0123456789', (mt_rand() % 10), 1); 842 $str .= $$pattern[$i]; 843 } 844 return $str; 811 /* 812 * Generate a cryptographically secure, random password. 813 * 814 * @access public 815 * @param int $bytes Length of password (in bytes) 816 * @return string Random string of characters. 817 * @author Quinn Comendant <quinn@strangecode.com> 818 * @version 1.0 819 * @since 15 Nov 2014 20:30:27 820 */ 821 public function generatePassword($bytes=10) 822 { 823 $app =& App::getInstance(); 824 825 $bytes = is_numeric($bytes) ? $bytes : 10; 826 $string = strtok(base64_encode(openssl_random_pseudo_bytes($bytes, $strong)), '='); 827 if (!$strong) { 828 $app->logMsg(sprintf('Password generated was not "cryptographically strong"; check your openssl.', null), LOG_NOTICE, __FILE__, __LINE__); 829 } 830 831 return $string; 845 832 } 846 833 … … 851 838 { 852 839 $app =& App::getInstance(); 840 841 $password = (string)$password; 853 842 854 843 // Existing password hashes rely on the same key/salt being used to compare encryptions. … … 858 847 switch ($this->_params['encryption_type']) { 859 848 case self::ENCRYPT_PLAINTEXT : 860 return$password;849 $encrypted_password = $password; 861 850 break; 862 851 863 852 case self::ENCRYPT_CRYPT : 864 // If comparing p laintext password with a hash, provide first two chars of the hashas the salt.865 return isset($salt) ? crypt($password, mb_substr($salt, 0, 2)) : crypt($password);853 // If comparing password with an existing hashed password, provide the hashed password as the salt. 854 $encrypted_password = isset($salt) ? crypt($password, $salt) : crypt($password); 866 855 break; 867 856 868 857 case self::ENCRYPT_SHA1 : 869 returnsha1($password);858 $encrypted_password = sha1($password); 870 859 break; 871 860 872 861 case self::ENCRYPT_SHA1_HARDENED : 873 $hash = sha1($app->getParam('signing_key') . $password . $more_salt); 874 // Increase key strength by 12 bits. 875 for ($i=0; $i < 4096; $i++) { 876 $hash = sha1($hash); 877 } 878 return $hash; 862 $encrypted_password = sha1($app->getParam('signing_key') . $password . $more_salt); 863 for ($i=0; $i < pow(2, 20); $i++) { 864 $encrypted_password = sha1($password . $encrypted_password); 865 } 879 866 break; 880 867 881 868 case self::ENCRYPT_MD5 : 882 returnmd5($password);869 $encrypted_password = md5($password); 883 870 break; 884 871 885 872 case self::ENCRYPT_MD5_HARDENED : 886 // Include salt to improve hash 887 $hash = md5($app->getParam('signing_key') . $password . $more_salt); 888 // Increase key strength by 12 bits. 889 for ($i=0; $i < 4096; $i++) { 890 $hash = md5($hash); 891 } 892 return $hash; 873 $encrypted_password = md5($app->getParam('signing_key') . $password . $more_salt); 874 for ($i=0; $i < pow(2, 20); $i++) { 875 $encrypted_password = md5($password . $encrypted_password); 876 } 877 break; 878 879 case self::ENCRYPT_PASSWORD_BCRYPT : 880 $encrypted_password = password_hash($password, PASSWORD_BCRYPT, array('cost' => 12)); 881 break; 882 883 case self::ENCRYPT_PASSWORD_DEFAULT : 884 $encrypted_password = password_hash($password, PASSWORD_DEFAULT, array('cost' => 12)); 893 885 break; 894 886 … … 897 889 return false; 898 890 break; 891 } 892 893 // In case our hashing function returns 'false' or another empty value, bail out. 894 if ('' == trim((string)$encrypted_password)) { 895 $app->logMsg(sprintf('Invalid password hash returned; check yo crypto!', null), LOG_ALERT, __FILE__, __LINE__); 896 return false; 897 } 898 899 return $encrypted_password; 900 } 901 902 /* 903 * 904 * 905 * @access public 906 * @param 907 * @return 908 * @author Quinn Comendant <quinn@strangecode.com> 909 * @version 1.0 910 * @since 15 Nov 2014 21:37:28 911 */ 912 public function verifyPassword($password, $encrypted_password) 913 { 914 switch ($this->_params['encryption_type']) { 915 case self::ENCRYPT_CRYPT : 916 return $this->encryptPassword($password, $encrypted_password) == $encrypted_password; 917 918 case self::ENCRYPT_PLAINTEXT : 919 case self::ENCRYPT_MD5 : 920 case self::ENCRYPT_MD5_HARDENED : 921 case self::ENCRYPT_SHA1 : 922 case self::ENCRYPT_SHA1_HARDENED : 923 default : 924 return $this->encryptPassword($password) == $encrypted_password; 925 926 case self::ENCRYPT_PASSWORD_BCRYPT : 927 case self::ENCRYPT_PASSWORD_DEFAULT : 928 return password_verify($password, $encrypted_password); 899 929 } 900 930 } … … 920 950 "); 921 951 if (!list($old_encrypted_password) = mysql_fetch_row($qid)) { 922 $app->logMsg(sprintf('Cannot set password for nonexistent user_id %s', $user_id), LOG_ NOTICE, __FILE__, __LINE__);952 $app->logMsg(sprintf('Cannot set password for nonexistent user_id %s', $user_id), LOG_WARNING, __FILE__, __LINE__); 923 953 return false; 924 954 } 925 955 926 956 // Compare old with new to ensure we're actually *changing* the password. 927 $encrypted_password = $this->encryptPassword($password); 928 if ($old_encrypted_password == $encrypted_password) { 957 if ($this->verifyPassword($password, $old_encrypted_password)) { 929 958 $app->logMsg(sprintf('Not setting password: new is the same as old.', null), LOG_INFO, __FILE__, __LINE__); 930 return false; 959 return null; 960 } 961 962 // Save the hash method used if a table exists for it. 963 $userpass_hashtype = ''; 964 if ($db->columnExists($this->_params['db_table'], 'userpass_hashtype', false)) { 965 $userpass_hashtype = ", userpass_hashtype = '" . $db->escapeString($this->getParam('encryption_type')) . "'"; 931 966 } 932 967 … … 934 969 $db->query(" 935 970 UPDATE " . $this->_params['db_table'] . " 936 SET userpass = '" . $db->escapeString($encrypted_password) . "' 971 SET userpass = '" . $db->escapeString($this->encryptPassword($password)) . "' 972 $userpass_hashtype 937 973 WHERE " . $this->_params['db_primary_key'] . " = '" . $db->escapeString($user_id) . "' 938 974 "); … … 943 979 } 944 980 981 $app->logMsg(sprintf('Password change successful for user_id %s', $user_id), LOG_INFO, __FILE__, __LINE__); 945 982 return true; 946 983 } … … 1008 1045 } 1009 1046 1010 /**1011 * If the current user has access to the specified $security_zone, return true.1012 * If the optional $user_type is supplied, test that against the zone.1013 *1014 * NOTE: "user_type" used to be called "priv" in some older implementations.1015 *1016 * @param constant $security_zone string of comma delimited privileges for the zone1017 * @param string $user_type a privilege that might be found in a zone1018 * @return bool true if user is a member of security zone, false otherwise1019 */1020 public function inClearanceZone($security_zone, $user_type='')1021 {1022 $zone_members = preg_split('/,\s*/', $security_zone);1023 $user_type = empty($user_type) ? $this->get('user_type') : $user_type;1024 1025 // If the current user's privilege level is NOT in that array or if the1026 // user has no privilege, return false. Otherwise the user is clear.1027 if (!in_array($user_type, $zone_members) || empty($user_type)) {1028 return false;1029 } else {1030 return true;1031 }1032 }1033 1034 /**1035 * This function tests a list of arguments $security_zone against the priv that the current user has.1036 * If the user doesn't have one of the supplied privs, die.1037 *1038 * NOTE: "user_type" used to be called "priv" in some older implementations.1039 *1040 * @param constant $security_zone string of comma delimited privileges for the zone1041 */1042 public function requireAccessClearance($security_zone, $message='')1043 {1044 $app =& App::getInstance();1045 1046 $zone_members = preg_split('/,\s*/', $security_zone);1047 1048 /* If the current user's privilege level is NOT in that array or if the1049 * user has no privilege, DIE with a message. */1050 if (!in_array($this->get('user_type'), $zone_members) || !$this->get('user_type')) {1051 $message = empty($message) ? _("You have insufficient privileges to view that page.") : $message;1052 $app->raiseMsg($message, MSG_NOTICE, __FILE__, __LINE__);1053 $app->dieBoomerangURL();1054 }1055 }1056 1057 1047 } // end class 1058 1059 // CIDR cheat-sheet1060 //1061 // Netmask Netmask (binary) CIDR Notes1062 // _____________________________________________________________________________1063 // 255.255.255.255 11111111.11111111.11111111.11111111 /32 Host (single addr)1064 // 255.255.255.254 11111111.11111111.11111111.11111110 /31 Unusable1065 // 255.255.255.252 11111111.11111111.11111111.11111100 /30 2 useable1066 // 255.255.255.248 11111111.11111111.11111111.11111000 /29 6 useable1067 // 255.255.255.240 11111111.11111111.11111111.11110000 /28 14 useable1068 // 255.255.255.224 11111111.11111111.11111111.11100000 /27 30 useable1069 // 255.255.255.192 11111111.11111111.11111111.11000000 /26 62 useable1070 // 255.255.255.128 11111111.11111111.11111111.10000000 /25 126 useable1071 // 255.255.255.0 11111111.11111111.11111111.00000000 /24 "Class C" 254 useable1072 //1073 // 255.255.254.0 11111111.11111111.11111110.00000000 /23 2 Class C's1074 // 255.255.252.0 11111111.11111111.11111100.00000000 /22 4 Class C's1075 // 255.255.248.0 11111111.11111111.11111000.00000000 /21 8 Class C's1076 // 255.255.240.0 11111111.11111111.11110000.00000000 /20 16 Class C's1077 // 255.255.224.0 11111111.11111111.11100000.00000000 /19 32 Class C's1078 // 255.255.192.0 11111111.11111111.11000000.00000000 /18 64 Class C's1079 // 255.255.128.0 11111111.11111111.10000000.00000000 /17 128 Class C's1080 // 255.255.0.0 11111111.11111111.00000000.00000000 /16 "Class B"1081 //1082 // 255.254.0.0 11111111.11111110.00000000.00000000 /15 2 Class B's1083 // 255.252.0.0 11111111.11111100.00000000.00000000 /14 4 Class B's1084 // 255.248.0.0 11111111.11111000.00000000.00000000 /13 8 Class B's1085 // 255.240.0.0 11111111.11110000.00000000.00000000 /12 16 Class B's1086 // 255.224.0.0 11111111.11100000.00000000.00000000 /11 32 Class B's1087 // 255.192.0.0 11111111.11000000.00000000.00000000 /10 64 Class B's1088 // 255.128.0.0 11111111.10000000.00000000.00000000 /9 128 Class B's1089 // 255.0.0.0 11111111.00000000.00000000.00000000 /8 "Class A"1090 //1091 // 254.0.0.0 11111110.00000000.00000000.00000000 /71092 // 252.0.0.0 11111100.00000000.00000000.00000000 /61093 // 248.0.0.0 11111000.00000000.00000000.00000000 /51094 // 240.0.0.0 11110000.00000000.00000000.00000000 /41095 // 224.0.0.0 11100000.00000000.00000000.00000000 /31096 // 192.0.0.0 11000000.00000000.00000000.00000000 /21097 // 128.0.0.0 10000000.00000000.00000000.00000000 /11098 // 0.0.0.0 00000000.00000000.00000000.00000000 /0 IP space -
trunk/lib/Currency.inc.php
r484 r500 4 4 * For details visit the project site: <http://trac.strangecode.com/codebase/> 5 5 * Copyright 2001-2012 Strangecode, LLC 6 * 6 * 7 7 * This file is part of The Strangecode Codebase. 8 8 * … … 11 11 * Free Software Foundation, either version 3 of the License, or (at your option) 12 12 * any later version. 13 * 13 * 14 14 * The Strangecode Codebase is distributed in the hope that it will be useful, but 15 15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 17 17 * details. 18 * 18 * 19 19 * You should have received a copy of the GNU General Public License along with 20 20 * The Strangecode Codebase. If not, see <http://www.gnu.org/licenses/>. … … 28 28 * @author Quinn Comendant <quinn@strangecode.com> 29 29 * @version 1.5 30 * 30 * 31 31 * Example of use: 32 32 --------------------------------------------------------------------- … … 37 37 --------------------------------------------------------------------- 38 38 */ 39 39 40 40 class Currency { 41 41 … … 48 48 'api_key' => '', // Used only by xurrency API. 49 49 ); 50 50 51 51 /** 52 52 * Cart constructor. … … 58 58 // Set custom parameters. 59 59 $this->setParam($params); 60 60 61 61 // Setup cache directory. 62 62 if ($this->getParam('cache_result')) { … … 66 66 } 67 67 if (!is_dir($this->getParam('cache_dir'))) { 68 $app->logMsg(sprintf('Creating cache_dir: %s', $this->getParam('cache_dir')), LOG_INFO, __FILE__, __LINE__); 68 $app->logMsg(sprintf('Creating cache_dir: %s', $this->getParam('cache_dir')), LOG_INFO, __FILE__, __LINE__); 69 69 if (!mkdir($this->getParam('cache_dir'))) { 70 $app->logMsg(sprintf('Could not create cache_dir: %s', $this->getParam('cache_dir')), LOG_WARNING, __FILE__, __LINE__); 70 $app->logMsg(sprintf('Could not create cache_dir: %s', $this->getParam('cache_dir')), LOG_WARNING, __FILE__, __LINE__); 71 71 } 72 72 } … … 97 97 { 98 98 $app =& App::getInstance(); 99 99 100 100 if (array_key_exists($param, $this->_params)) { 101 101 return $this->_params[$param]; … … 105 105 } 106 106 } 107 107 108 108 /* 109 109 * Return the exchange value between the two given currencies for given amount. … … 113 113 * @param string $base 3-letter currency code to convert from. 114 114 * @param string $target 3-letter currency code to convert to. 115 * @return mixed Float converted currency value, or false on error. 115 * @return mixed Float converted currency value, or false on error. 116 116 * @author Quinn Comendant <quinn@strangecode.com> 117 117 * @version 1.0 … … 121 121 { 122 122 if (false !== $rate = $this->getRate($base, $target)) { 123 return abs($rate * $amount); 123 return abs($rate * $amount); 124 124 } else { 125 125 return false; 126 126 } 127 127 } 128 128 129 129 /* 130 130 * Return the currency conversion rate as a ratio. … … 133 133 * @param string $base 3-letter currency code to convert from. 134 134 * @param string $target 3-letter currency code to convert to. 135 * @return mixed Float exchange rate value, or false on error. 135 * @return mixed Float exchange rate value, or false on error. 136 136 * @author Quinn Comendant <quinn@strangecode.com> 137 137 * @version 1.0 … … 173 173 return trim($value); 174 174 } 175 175 176 176 /** 177 177 * @param string … … 215 215 $api_url = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'; 216 216 if (false === $sXML = file_get_contents($api_url)) { 217 $app->logMsg(sprintf('Failed to load ECB XML data from 217 $app->logMsg(sprintf('Failed to load ECB XML data from: %s', $api_url), LOG_WARNING, __FILE__, __LINE__); 218 218 return false; 219 219 } 220 220 if (false === $oXML = simplexml_load_string($sXML)) { 221 $app->logMsg(sprintf('Failed to decode ECB XML data: ', truncate($sXML, 200, 'end')), LOG_WARNING, __FILE__, __LINE__);221 $app->logMsg(sprintf('Failed to decode ECB XML data: %s', truncate($sXML, 200, 'end')), LOG_WARNING, __FILE__, __LINE__); 222 222 return false; 223 223 } -
trunk/lib/Email.inc.php
r490 r500 314 314 foreach ($headers as $key => $val) { 315 315 // Validate key and values. 316 if (empty($key) || empty($val) || !is_string($key) || !is_string($val) || preg_match("/[\n\r]/", $key . $val) || preg_match('/[^\w-]/', $key)) { 317 $app->logMsg(sprintf('Broken headers provided: %s=%s', $key, $val), LOG_WARNING, __FILE__, __LINE__); 316 if (empty($val)) { 317 $app->logMsg(sprintf('Empty email header provided: %s', $key), LOG_DEBUG, __FILE__, __LINE__); 318 continue; 319 } 320 if (empty($key) || !is_string($key) || !is_string($val) || preg_match("/[\n\r]/", $key . $val) || preg_match('/[^\w-]/', $key)) { 321 $app->logMsg(sprintf('Broken email header provided: %s=%s', $key, $val), LOG_WARNING, __FILE__, __LINE__); 318 322 continue; 319 323 } -
trunk/lib/HTML.inc.php
r497 r500 39 39 40 40 class HTML { 41 42 // Browsers add names and ids of form controls as properties to the FORM. This results in the properties of the form being replaced. 43 // Use this list to warn the programmer if he uses an unsafe name. 44 // http://jibbering.com/faq/names/unsafe_names.html 45 static $unsafe_form_control_names = array('accept','acceptCharset','action','addBehavior','addEventListener','addEventSource','addRepetitionBlock','addRepetitionBlockByIndex','all','appendChild','applyElement','ariaBusy','ariaChecked','ariaControls','ariaDescribability','ariaDisabled','ariaExpanded','ariaFlowto','ariaHaspopup','ariaHidden','ariaInvalid','ariaLabelledby','ariaLevel','ariaMultiselect','ariaOwns','ariaPosinset','ariaPressed','ariaReadonly','ariaRequired','ariaSecret','ariaSelected','ariaSetsize','ariaValuemax','ariaValuemin','ariaValuenow','attachEvent','attributes','ATTRIBUTE_NODE','autocomplete','baseURI','behaviorUrns','blockDiraction','blur','canHaveChildren','canHaveHTML','CDATA_SECTION_NODE','checkValidity','childElementCount','childNodes','children','className','clearAttributes','click','clientHeight','clientLeft','clientTop','clientWidth','cloneNode','COMMENT_NODE','compareDocumentPosition','componentFromPoint','constructor','contains','contentEditable','currentStyle','data','detachEvent','dir','dispatchEvent','dispatchFormChange','dispatchFormInput','document','DOCUMENT_FRAGMENT_NODE','DOCUMENT_NODE','DOCUMENT_POSITION_CONTAINED_BY','DOCUMENT_POSITION_CONTAINS','DOCUMENT_POSITION_DISCONNECTED','DOCUMENT_POSITION_FOLLOWING','DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC','DOCUMENT_POSITION_PRECEDING','DOCUMENT_TYPE_NODE','dragDrop','elements','ELEMENT_NODE','encoding','enctype','ENTITY_NODE','ENTITY_REFERENCE_NODE','fireEvent','firstChild','firstElementChild','focus','getAdjacentText','getAttribute','getAttributeNode','getAttributeNodeNS','getAttributeNS','getBoundingClientRect','getClientRects','getElementsByClassName','getElementsByTagName','getElementsByTagNameNS','getExpression','getFeature','getUserData','hasAttribute','hasAttributeNS','hasAttributes','hasChildNodes','hasOwnProperty','hideFocus','id','innerHTML','innerText','insertAdjacentElement','insertAdjacentHTML','insertAdjacentText','insertBefore','isContentEditable','isDefaultNamespace','isDefaultNamespaceURI','isDisabled','isEqualNode','isMultiLine','isPrototypeOf','isSameNode','isSupported','isTextEdit','item','lang','language','lastChild','lastElementChild','length','localName','lookupPrefix','mergeAttributes','method','moveRepetitionBlock','msBlockProgression','msBoxSizing','name','namedItem','namespaceURI','nextSibling','nodeName','nodeType','nodeValue','normalize','NOTATION_NODE','offsetHeight','offsetWidth','onabort','onactivate','onbeforeactivate','onbeforecopy','onbeforecut','onbeforedeactivate','onbeforeeditfocus','onbeforepaste','onblur','onchage','onclick','onclosecapture','oncontextmenu','oncopy','oncut','ondblclick','ondeactivate','ondrag','ondragend','ondragenter','ondragleave','ondragover','onerror','onfocus','onfocusin','onfocusout','onhelp','oninput','onkeydown','onkeypress','onkeyup','onmousedown','onmouseenter','onmouseleave','onmousemove','onmousemultiwheel','onmouseout','onmouseover','onmouseup','onmousewheel','onmove','onmoveend','onmovestart','onOffBehavior','onpaste','onpropertychange','onreadystatechange','onresize','onresizeend','onresizestart','onscroll','onsearch','onselect','onselectstart','ontimeerror','onunload','outerHTML','outerText','ownerDocument','parentNode','parentTextEdit','prefix','previousElementSibling','previousSibling','PROCESSING_INSTRUCTION_NODE','propertyIsEnumerable','querySelector','querySelectorAll','quotes','releaseCapture','removeAttribute','removeAttributeNode','removeAttributeNS','removeBehavior','removeChild','removeEventListener','removeEventSource','removeExpression','removeNode','removeRepetitionBlock','repeatMax','repeatMin','repeatStart','repetitionBlocks','repetitionIndex','repetitionTemplate','repetitionType','replace','replaceAdjacentText','replaceChild','replaceNode','reset','resetFromData','role','runtimeStyle','schemaTypeInfo','scopeName','scrollByLines','scrollByPages','scrollHeight','scrollIntoView','scrollLeft','scrollTop','scrollWidth','selectNodes','selectSingleNode','setActive','setAttributeNode','setAttributeNodeNS','setAttributeNS','setCapture','setExpression','setIdAttribute','setIdAttributeNode','setIdAttributeNS','setUserData','sourceIndex','spellcheck','style','submit','swapNode','tabIndex','tagName','tagUrn','target','templateElements','text','textContent','TEXT_NODE','title','toLocaleString','toString','uniqueID','unselectable','unwatch','urns','valueOf','watch','window'); 41 46 42 47 /** … … 53 58 static public function printButtons($buttons=array(), $class='button-group') 54 59 { 60 $app =& App::getInstance(); 61 55 62 if (!isset($buttons[0]) || !is_array($buttons[0])) { 56 63 $app =& App::getInstance(); … … 73 80 echo '>' . oTxt($b['value']) . '</a></li>'; 74 81 } else if (isset($b['name'])) { 82 if (in_array($b['name'], self::$unsafe_form_control_names)) { 83 $app->logMsg(sprintf('Unsafe form control name: %s', $b['name']), LOG_NOTICE, __FILE__, __LINE__); 84 } 75 85 $defaults['id'] = isset($b['id']) ? $b['id'] : sprintf('sc-%s-button', $b['name']); 76 86 echo '<li><input'; -
trunk/lib/Utilities.inc.php
r497 r500 945 945 * environment variable set in httpd.conf is a good place. 946 946 * 947 * TODO: consider using more bits-per-character, such as done with: 948 * http://www.php.net/manual/en/function.sha1.php#86239 949 * http://blog.kevburnsjr.com/php-unique-hash 950 * 947 951 * @access public 948 952 * @param string $val The string to sign. … … 964 968 } 965 969 966 // TODO: consider using more bits-per-character, such as done with: 967 // http://www.php.net/manual/en/function.sha1.php#86239 968 // http://blog.kevburnsjr.com/php-unique-hash 969 return $val . '-' . mb_strtolower(mb_substr(md5($salt . md5($val . $salt)), 0, $length)); 970 switch ($app->getParam('signing_method')) { 971 case 'sha512+base64': 972 return $val . '-' . mb_substr(preg_replace('/[^\w]/', '', base64_encode(hash('sha512', $val . $salt, true))), 0, $length); 973 974 case 'md5': 975 default: 976 return $val . '-' . mb_strtolower(mb_substr(md5($salt . md5($val . $salt)), 0, $length)); 977 } 970 978 } 971 979 … … 986 994 987 995 /** 988 * Verifies a signature appen ed to a value by addSignature().996 * Verifies a signature appended to a value by addSignature(). 989 997 * 990 998 * @access public … … 995 1003 function verifySignature($signed_val, $salt=null, $length=18) 996 1004 { 997 // All comparisons are done using lower-case strings.998 $signed_val = mb_strtolower($signed_val);999 1005 // Strip the value from the signed value. 1000 1006 $val = removeSignature($signed_val); … … 1004 1010 return true; 1005 1011 } else { 1012 $app =& App::getInstance(); 1013 $app->logMsg(sprintf('Failed signature (%s should be %s)', $signed_val, addSignature($val, $salt, $length)), LOG_DEBUG, __FILE__, __LINE__); 1006 1014 return false; 1007 1015 } … … 1255 1263 } 1256 1264 } 1257 -
trunk/lib/Validator.inc.php
r490 r500 162 162 static public function stringLength($val, $min, $max) 163 163 { 164 return mb_strlen( trim((string)$val)) >= $min && mb_strlen($val) <= $max;164 return mb_strlen((string)$val) >= $min && mb_strlen((string)$val) <= $max; 165 165 } 166 166
Note: See TracChangeset
for help on using the changeset viewer.