Project

General

Profile

« Previous | Next » 

Revision 1903

Added by darkviper over 11 years ago

some typofixes in class PassWord
class /framework/PasswordHash never needed(replaced by /include/phpass/PasswordHash

View differences:

branches/2.8.x/CHANGELOG
11 11
! = Update/Change
12 12
===============================================================================
13 13

  
14
13 May-2013 Build 1903 Werner v.d.Decken(DarkViper)
15
! some typofixes in class PassWord
16
- class /framework/PasswordHash never needed(replaced by /include/phpass/PasswordHash
14 17
12 May-2013 Build 1902 Werner v.d.Decken(DarkViper)
15 18
+ added posssibility to use different adaptors for each module
16 19
+ added new adaptor to access language definitions in a MySQL database
branches/2.8.x/wb/admin/interface/version.php
51 51

  
52 52
// check if defined to avoid errors during installation (redirect to admin panel fails if PHP error/warnings are enabled)
53 53
if(!defined('VERSION')) define('VERSION', '2.8.3');
54
if(!defined('REVISION')) define('REVISION', '1902');
54
if(!defined('REVISION')) define('REVISION', '1903');
55 55
if(!defined('SP')) define('SP', '');
branches/2.8.x/wb/framework/PasswordHash.php
1
<?php
2
/**
3
 * @category     Core
4
 * @package      Core_security
5
 * @author       Werner v.d.Decken
6
 * @copyright    ISTeasy-project(http://isteasy.de/)
7
 * @license      Creative Commons BY-SA 3.0 http://creativecommons.org/licenses/by-sa/3.0/
8
 * @version      $Id$
9
 * @filesource   $HeadURL:$
10
 * @since        Datei vorhanden seit Release 2.8.2
11
 * @lastmodified $Date:$
12
 *
13
 * this class works with salted md5-hashes with several rounds. 
14
 * For backward compatibility it can compare normal md5-hashes also.
15
 * Minimum requirements: PHP 5.2.2 or higher
16
 *
17
 * *****************************************************************************
18
 * This class is based on the Portable PHP password hashing framework.
19
 * Version 0.3 / genuine. Written by Solar Designer <solar at openwall.com>
20
 * in 2004-2006 and placed in the public domain. Revised in subsequent years,
21
 * still public domain. There's absolutely no warranty.
22
 * The homepage URL for this framework is: http://www.openwall.com/phpass/
23
 * *****************************************************************************
24
 */
25
class PasswordHash {
26

  
27
	const SECURITY_WEAK      = 6;
28
	const SECURITY_MEDIUM    = 8;
29
	const SECURITY_NORMAL    = 10;
30
	const SECURITY_STRONG    = 12;
31
	const SECURITY_STRONGER  = 16;
32

  
33
	private $_itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
34
	private $_iterationCountLog2 = 8;
35
	private $_portableHashes = true;
36
	private $_randomState = '';
37
	
38
	/**
39
	 * @param int $iterationCountLog2 number of iterations as exponent of 2
40
	 * @param bool $portableHashes TRUE = use MD5 only | FALSE = automatic
41
	 */
42
	public function __construct($iterationCountLog2, $portableHashes = true)
43
	{
44

  
45
		if ($iterationCountLog2 < 4 || $iterationCountLog2 > 31) {
46
			$iterationCountLog2 = 8;
47
		}
48
		$this->_iterationCountLog2 = $iterationCountLog2;
49
		$this->_portableHashes = $portableHashes;
50
		$this->_randomState = microtime();
51
		if (function_exists('getmypid')) {
52
			$this->_randomState .= getmypid();
53
		}
54
	}
55

  
56

  
57
	private function _getRandomBytes($count)
58
	{
59
		$output = '';
60
		if (is_readable('/dev/urandom') && ($fh = @fopen('/dev/urandom', 'rb'))) {
61
			$output = fread($fh, $count);
62
			fclose($fh);
63
		}
64
		if (strlen($output) < $count) {
65
			$output = '';
66
			for ($i = 0; $i < $count; $i += 16) {
67
				$this->_randomState = md5(microtime() . $this->_randomState);
68
				$output .= pack('H*', md5($this->_randomState));
69
			}
70
			$output = substr($output, 0, $count);
71
		}
72
		return $output;
73
	}
74

  
75
	private function _Encode64($input, $count)
76
	{
77
		$output = '';
78
		$i = 0;
79
		do {
80
			$value = ord($input[$i++]);
81
			$output .= $this->_itoa64[$value & 0x3f];
82
			if ($i < $count) {
83
				$value |= ord($input[$i]) << 8;
84
			}
85
			$output .= $this->_itoa64[($value >> 6) & 0x3f];
86
			if ($i++ >= $count) { break; }
87
			if ($i < $count) {
88
				$value |= ord($input[$i]) << 16;
89
			}
90
			$output .= $this->_itoa64[($value >> 12) & 0x3f];
91
			if ($i++ >= $count) { break; }
92
			$output .= $this->_itoa64[($value >> 18) & 0x3f];
93
		} while ($i < $count);
94
		return $output;
95
	}
96

  
97
	private function _GenSaltPrivate($input)
98
	{
99
		$output = '$P$';
100
		$output .= $this->_itoa64[min($this->_iterationCountLog2 + 5, 30)];
101
		$output .= $this->_Encode64($input, 6);
102
		return $output;
103
	}
104

  
105
	private function _CryptPrivate($password, $setting)
106
	{
107
		$output = '*0';
108
		if (substr($setting, 0, 2) == $output) {
109
			$output = '*1';
110
		}
111
		$id = substr($setting, 0, 3);
112
		# We use "$P$", phpBB3 uses "$H$" for the same thing
113
		if ($id != '$P$' && $id != '$H$') {
114
			return $output;
115
		}
116
		$count_log2 = strpos($this->_itoa64, $setting[3]);
117
		if ($count_log2 < 7 || $count_log2 > 30) {
118
			return $output;
119
		}
120
		$count = 1 << $count_log2;
121
		$salt = substr($setting, 4, 8);
122
		if (strlen($salt) != 8) {
123
			return $output;
124
		}
125
		# We're kind of forced to use MD5 here since it's the only
126
		# cryptographic primitive available in all versions of PHP
127
		# currently in use.  To implement our own low-level crypto
128
		# in PHP would result in much worse performance and
129
		# consequently in lower iteration counts and hashes that are
130
		# quicker to crack (by non-PHP code).
131
		$hash = md5($salt . $password, TRUE);
132
		do {
133
			$hash = md5($hash . $password, TRUE);
134
		} while (--$count);
135
		$output = substr($setting, 0, 12);
136
		$output .= $this->_Encode64($hash, 16);
137
		return $output;
138
	}
139

  
140
	/**
141
	 * calculate the hash from a given password
142
	 * @param string $password password as original string
143
	 * @return string generated hash | '*' on error
144
	 */
145
	public function HashPassword($password, $md5 = false)
146
	{
147
		if ($md5) { return(md5($password)); }
148
		$random = '';
149
		if (strlen($random) < 6) {
150
			$random = $this->_getRandomBytes(6);
151
		}
152
		$hash = $this->_CryptPrivate($password, $this->_GenSaltPrivate($random));
153
		if (strlen($hash) == 34) {
154
			return $hash;
155
		}
156
		# Returning '*' on error is safe here, but would _not_ be safe
157
		# in a crypt(3)-like function used _both_ for generating new
158
		# hashes and for validating passwords against existing hashes.
159
		return '*';
160
	}
161

  
162
	/**
163
	 * encodes the password and compare it against the given hash
164
	 * @param string $password clear password
165
	 * @param string $stored_hash the hash to compare against
166
	 * @return bool
167
	 */
168
	public function CheckPassword($password, $stored_hash)
169
	{
170
	// compare against a normal, simple md5-hash
171
		if(preg_match('/^[0-9a-f]{32}$/i', $stored_hash)) {
172
			return md5($password) == $stored_hash;
173
		}
174
	// compare against a rounded, salted md5-hash
175
		$hash = $this->_CryptPrivate($password, $stored_hash);
176
		if ($hash[0] == '*') {
177
			$hash = crypt($password, $stored_hash);
178
		}
179
		return $hash == $stored_hash;
180
	}
181
	/**
182
	 * generate a case sensitive mnemonic password including numbers and special chars
183
	 * makes no use of lowercase 'l', uppercase 'I', 'O' or number '0'
184
	 * @param int $length length of the generated password. default = 8
185
	 * @return string
186
	 */
187
	public static function NewPassword($length = self::SECURITY_MEDIUM)
188
	{
189
		$chars = array(
190
			array('b','c','d','f','g','h','j','k','l','m','n','p','r','s','t','v','w','x','y','z'),
191
			array('a','e','i','o','u'),
192
			array('!','-','@','_',':','.','+','%','/','*')
193
		);
194
		if($length < self::SECURITY_WEAK) { $length = self::SECURITY_WEAK; }
195
		$length = ceil($length / 2);
196
		$Password = array();
197
	// at first fill array alternating with vowels and consonants
198
		for($x = 0; $x < $length; $x++) {
199
			$char = $chars[0][rand(1000, 10000) % sizeof($chars[0])];
200
			$Password[] = $char == 'l' ? 'L' : $char;
201
			$Password[] = $chars[1][rand(1000, 10000) % sizeof($chars[1])];
202
		}
203
	// transform some random chars into uppercase
204
		$pos = ((rand(1000, 10000) % 3) + 1);
205
		while($pos < sizeof($Password)) {
206
			$Password[$pos] = ($Password[$pos] == 'i' || $Password[$pos] == 'o')
207
			                  ? $Password[$pos] : strtoupper($Password[$pos]);
208
			$pos += ((rand(1000, 10000) % 3) + 1);
209
		}
210
	// insert some numeric chars, between 1 and 9
211
		$specialChars = array();
212
		$specialCharsCount = floor(sizeof($Password) / 4);
213
		while(sizeof($specialChars) < $specialCharsCount) {
214
			$key = (rand(1000, 10000) % sizeof($Password));
215
			if(!isset($specialChars[$key])) {
216
				$specialChars[$key] = (rand(1000, 10000) % 9) + 1;
217
			}
218
		}
219
	// insert some punctuation chars, but not leading or trailing
220
		$specialCharsCount += floor((sizeof($Password)-1) / 6);
221
		while(sizeof($specialChars) < $specialCharsCount) {
222
			$key = (rand(1000, 10000) % (sizeof($Password)-2))+1;
223
			if(!isset($specialChars[$key])) {
224
				$specialChars[$key] = $chars[2][(rand(1000, 10000) % sizeof($chars[2]))];
225
			}
226
		}
227
		foreach($specialChars as $key=>$val) {
228
			$Password[$key] = $val;
229
		}
230

  
231
		return implode($Password);
232
	}
233

  
234
} // end of class
branches/2.8.x/wb/framework/Password.php
16 16
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 17
 */
18 18
/**
19
 * Description of Password
20
 * *****************************************************************************
21
 * This class is interfacing the Portable PHP password hashing framework.
22
 * Version 0.4 / ISTeam Rev. 0.1
23
 * ISTeam changes: added SHA-256, SHA-512 (2012/10/27 Werner v.d. Decken)
24
 * *****************************************************************************
25
 *
26 19
 * @category     WBCore
27 20
 * @package      WBCore_Security
28 21
 * @author       Werner v.d. Decken <wkl@isteam.de>
......
33 26
 * @link         $HeadURL$
34 27
 * @lastmodified $Date$
35 28
 * @since        Datei vorhanden seit Release 1.2.0
29
 * @description  This class is interfacing the Portable PHP password hashing framework.<br />
30
 *               Version 0.4 / ISTeam Rev. 0.1<br />
31
 *               ISTeam changes: added SHA-256, SHA-512 (2012/10/27 Werner v.d. Decken)
36 32
 */
37 33

  
38
// use \vendors\phpass\PasswordHash;
34
// backwardcompatibility for PHP 5.2.2 + WB2.8.x
39 35
if(!class_exists('PasswordHash')) {
40 36
	include(dirname(dirname(__FILE__)).'/include/phpass/PasswordHash.php'); 
41 37
}
42 38

  
43 39

  
44 40
class Password extends PasswordHash
45
//class Password extends v_phpass_PasswordHash
41
//class Password extends vendors\phpass\PasswordHash
46 42
{
47 43

  
48
	const MIN_CRYPT_LOOPS     =  6;  // minimum numbers of loops is 2^6 (64) very, very quick
49
	const MAX_CRYPT_LOOPS     = 31;  // maximum numbers of loops is 2^31 (2,147,483,648) extremely slow
50
	const DEFAULT_CRYPT_LOOPS = 12;  // default numbers of loopf is 2^12 (4096) a good average
44
	const CRYPT_LOOPS_MIN     =  6;  // minimum numbers of loops is 2^6 (64) very, very quick
45
	const CRYPT_LOOPS_MAX     = 31;  // maximum numbers of loops is 2^31 (2,147,483,648) extremely slow
46
	const CRYPT_LOOPS_DEFAULT = 12;  // default numbers of loopf is 2^12 (4096) a good average
51 47

  
52 48
	const HASH_TYPE_PORTABLE  = true;  // use MD5 only
53 49
	const HASH_TYPE_AUTO      = false; // select highest available crypting methode
54 50

  
55
	const MIN_PW_LENGTH       =   6;
56
	const MAX_PW_LENGTH       = 100;
57
	const DEFAULT_PW_LENGTH   =  10;
51
	const PW_LENGTH_MIN       =   6;
52
	const PW_LENGTH_MAX       = 100;
53
	const PW_LENGTH_DEFAULT   =  10;
58 54

  
59 55
	const PW_USE_LOWERCHAR    = 0x0001; // use lower chars
60 56
	const PW_USE_UPPERCHAR    = 0x0002; // use upper chars
......
67 63
 * @param int number of iterations as exponent of 2 (must be between 4 and 31)
68 64
 * @param bool TRUE = use MD5 only | FALSE = automatic
69 65
 */
70
	public function __construct($iIterationCountLog2 = self::DEFAULT_CRYPT_LOOPS, $bPortableHashes = self::HASH_TYPE_AUTO)
66
	public function __construct($iIterationCountLog2 = self::CRYPT_LOOPS_DEFAULT, $bPortableHashes = self::HASH_TYPE_AUTO)
71 67
	{
72 68
		parent::__construct($iIterationCountLog2, $bPortableHashes);
73 69
	}
......
96 92
/**
97 93
 * generate a case sensitive mnemonic password including numbers and special chars
98 94
 * makes no use of confusing characters like 'O' and '0' and so on.
99
 * @param int length of the generated password. default = DEFAULT_PW_LENGTH
95
 * @param int length of the generated password. default = PW_LENGTH_DEFAULT
100 96
 * @param int defines which elemets are used to generate a password. Default = PW_USE_ALL
101 97
 * @return string
102 98
 */
103
	public static function createNew($iLength = self::DEFAULT_PW_LENGTH, $iElements = self::PW_USE_ALL)
99
	public static function createNew($iLength = self::PW_LENGTH_DEFAULT, $iElements = self::PW_USE_ALL)
104 100
	{
105 101
		$aChars = array(
106 102
			array('b','c','d','f','g','h','j','k','m','n','p','q','r','s','t','v','w','x','y','z'),
......
110 106
			array('!','-','@','_',':','.','+','%','/','*')
111 107
		);
112 108
		$iElements = ($iElements & self::PW_USE_ALL) == 0 ? self::PW_USE_ALL : $iElements;
113
		if(($iLength < self::MIN_PW_LENGTH) || ($iLength > self::MAX_PW_LENGTH)) {
114
			$iLength = self::DEFAULT_PW_LENGTH;
109
		if(($iLength < self::PW_LENGTH_MIN) || ($iLength > self::PW_LENGTH_MAX)) {
110
			$iLength = self::PW_LENGTH_DEFAULT;
115 111
		}
116 112
	// at first create random arrays of lowerchars and uperchars
117 113
	// alternating between vowels and consonants
......
119 115
		$aLowerCase = array();
120 116
		for($x = 0; $x < ceil($iLength / 2); $x++) {
121 117
			// consonants
122
			$y = rand(1000, 10000) % sizeof($aChars[0]);
123
			$aLowerCase[] = $aChars[0][$y];
124
			$y = rand(1000, 10000) % sizeof($aChars[1]);
125
			$aUpperCase[] = $aChars[1][$y];
118
			$i1 = rand(1000, 10000) % sizeof($aChars[0]);
119
			$aLowerCase[] = $aChars[0][$i1];
120
			$i2 = rand(1000, 10000) % sizeof($aChars[1]);
121
			$aUpperCase[] = $aChars[1][$i2];
126 122
			// vowels
127
			$y = rand(1000, 10000) % sizeof($aChars[2]);
128
			$aLowerCase[] = $aChars[2][$y];
129
			$y = rand(1000, 10000) % sizeof($aChars[3]);
130
			$aUpperCase[] = $aChars[3][$y];
123
			$i3 = rand(1000, 10000) % sizeof($aChars[2]);
124
			$aLowerCase[] = $aChars[2][$i3];
125
			$i4 = rand(1000, 10000) % sizeof($aChars[3]);
126
			$aUpperCase[] = $aChars[3][$i4];
131 127
		}
132 128
	// create random arrays of numeric digits 2-9 and  special chars
133 129
		$aDigits       = array();
......
154 150
		}
155 151
		if($iElements & self::PW_USE_DIGITS) {
156 152
			if($bMerge) {
157
				$iNumberOfDigits = (rand(1000, 10000) % ceil($iLength / 2.5));
158
				$iNumberOfDigits = $iNumberOfDigits ? $iNumberOfDigits : 1;
153
				$x = (rand(1000, 10000) % ceil($iLength / 2.5));
154
				$iNumberOfDigits = $x ? $x : 1;
159 155
				$aPassword = self::_mergeIntoPassword($aPassword, $aDigits, $iNumberOfDigits);
160 156
			}else {
161 157
				$aPassword = $aDigits;
......
164 160
		}
165 161
		if($iElements & self::PW_USE_SPECIAL) {
166 162
			if($bMerge) {
167
				$iNumberOfSpecialChars = rand(1000, 10000) % ceil($iLength / 5);
168
				$iNumberOfSpecialChars = $iNumberOfSpecialChars ? $iNumberOfSpecialChars : 1;
163
				$x = rand(1000, 10000) % ceil($iLength / 5);
164
				$iNumberOfSpecialChars = $x ? $x : 1;
169 165
				$aPassword = self::_mergeIntoPassword($aPassword, $aSpecialChars, $iNumberOfSpecialChars);
170 166
			}else {
171 167
				$aPassword = $aSpecialChars;

Also available in: Unified diff