[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 /* 3 Copyright (c) 2002-2010, Michael Bretterklieber <michael@bretterklieber.com> 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions 8 are met: 9 10 1. Redistributions of source code must retain the above copyright 11 notice, this list of conditions and the following disclaimer. 12 2. Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions and the following disclaimer in the 14 documentation and/or other materials provided with the distribution. 15 3. The names of the authors may not be used to endorse or promote products 16 derived from this software without specific prior written permission. 17 18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 25 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 This code cannot simply be copied and put under the GNU Public License or 30 any other GPL-like (LGPL, GPL2) License. 31 32 $Id$ 33 */ 34 35 require_once 'PEAR.php'; 36 37 /** 38 * Classes for generating packets for various CHAP Protocols: 39 * CHAP-MD5: RFC1994 40 * MS-CHAPv1: RFC2433 41 * MS-CHAPv2: RFC2759 42 * 43 * @package Crypt_CHAP 44 * @author Michael Bretterklieber <michael@bretterklieber.com> 45 * @access public 46 * @version $Revision$ 47 */ 48 49 /** 50 * class Crypt_CHAP 51 * 52 * Abstract base class for CHAP 53 * 54 * @package Crypt_CHAP 55 */ 56 class Crypt_CHAP extends PEAR 57 { 58 /** 59 * Random binary challenge 60 * @var string 61 */ 62 var $challenge = null; 63 64 /** 65 * Binary response 66 * @var string 67 */ 68 var $response = null; 69 70 /** 71 * User password 72 * @var string 73 */ 74 var $password = null; 75 76 /** 77 * Id of the authentication request. Should incremented after every request. 78 * @var integer 79 */ 80 var $chapid = 1; 81 82 /** 83 * Constructor 84 * 85 * Generates a random challenge 86 * @return void 87 */ 88 public function __construct() 89 { 90 parent::__construct(); 91 $this->generateChallenge(); 92 } 93 94 function Crypt_CHAP() 95 { 96 debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER); 97 self::__construct(); 98 } 99 100 /** 101 * Generates a random binary challenge 102 * 103 * @param string $varname Name of the property 104 * @param integer $size Size of the challenge in Bytes 105 * @return void 106 */ 107 function generateChallenge($varname = 'challenge', $size = 8) 108 { 109 $this->$varname = ''; 110 for ($i = 0; $i < $size; $i++) { 111 $this->$varname .= pack('C', 1 + mt_rand() % 255); 112 } 113 return $this->$varname; 114 } 115 116 /** 117 * Generates the response. Overwrite this. 118 * 119 * @return void 120 */ 121 function challengeResponse() 122 { 123 } 124 125 } 126 127 /** 128 * class Crypt_CHAP_MD5 129 * 130 * Generate CHAP-MD5 Packets 131 * 132 * @package Crypt_CHAP 133 */ 134 class Crypt_CHAP_MD5 extends Crypt_CHAP 135 { 136 137 /** 138 * Generates the response. 139 * 140 * CHAP-MD5 uses MD5-Hash for generating the response. The Hash consists 141 * of the chapid, the plaintext password and the challenge. 142 * 143 * @return string 144 */ 145 function challengeResponse() 146 { 147 return pack('H*', md5(pack('C', $this->chapid) . $this->password . $this->challenge)); 148 } 149 } 150 151 /** 152 * class Crypt_CHAP_MSv1 153 * 154 * Generate MS-CHAPv1 Packets. MS-CHAP doesen't use the plaintext password, it uses the 155 * NT-HASH wich is stored in the SAM-Database or in the smbpasswd, if you are using samba. 156 * The NT-HASH is MD4(str2unicode(plaintextpass)). 157 * You need the hash extension for this class. 158 * 159 * @package Crypt_CHAP 160 */ 161 class Crypt_CHAP_MSv1 extends Crypt_CHAP 162 { 163 /** 164 * Wether using deprecated LM-Responses or not. 165 * 0 = use LM-Response, 1 = use NT-Response 166 * @var bool 167 */ 168 var $flags = 1; 169 170 /** 171 * Constructor 172 * 173 * Loads the hash extension 174 * @return void 175 */ 176 public function __construct() 177 { 178 parent::__construct(); 179 $this->loadExtension('hash'); 180 } 181 182 function Crypt_CHAP_MSv1() 183 { 184 debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER); 185 self::__construct(); 186 } 187 188 /** 189 * Generates the NT-HASH from the given plaintext password. 190 * 191 * @access public 192 * @return string 193 */ 194 function ntPasswordHash($password = null) 195 { 196 if (isset($password)) { 197 return pack('H*',hash('md4', $this->str2unicode($password))); 198 } else { 199 return pack('H*',hash('md4', $this->str2unicode($this->password))); 200 } 201 } 202 203 /** 204 * Converts ascii to unicode. 205 * 206 * @access public 207 * @return string 208 */ 209 function str2unicode($str) 210 { 211 $uni = ''; 212 $str = (string) $str; 213 for ($i = 0; $i < strlen($str); $i++) { 214 $a = ord($str{$i}) << 8; 215 $uni .= sprintf("%X", $a); 216 } 217 return pack('H*', $uni); 218 } 219 220 /** 221 * Generates the NT-Response. 222 * 223 * @access public 224 * @return string 225 */ 226 function challengeResponse() 227 { 228 return $this->_challengeResponse(); 229 } 230 231 /** 232 * Generates the NT-Response. 233 * 234 * @access public 235 * @return string 236 */ 237 function ntChallengeResponse() 238 { 239 return $this->_challengeResponse(false); 240 } 241 242 /** 243 * Generates the LAN-Manager-Response. 244 * 245 * @access public 246 * @return string 247 */ 248 function lmChallengeResponse() 249 { 250 return $this->_challengeResponse(true); 251 } 252 253 /** 254 * Generates the response. 255 * 256 * Generates the response using DES. 257 * 258 * @param bool $lm wether generating LAN-Manager-Response 259 * @access private 260 * @return string 261 */ 262 function _challengeResponse($lm = false) 263 { 264 if ($lm) { 265 $hash = $this->lmPasswordHash(); 266 } else { 267 $hash = $this->ntPasswordHash(); 268 } 269 270 while (strlen($hash) < 21) { 271 $hash .= "\0"; 272 } 273 274 $td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, ''); 275 $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); 276 $key = $this->_desAddParity(substr($hash, 0, 7)); 277 mcrypt_generic_init($td, $key, $iv); 278 $resp1 = mcrypt_generic($td, $this->challenge); 279 mcrypt_generic_deinit($td); 280 281 $key = $this->_desAddParity(substr($hash, 7, 7)); 282 mcrypt_generic_init($td, $key, $iv); 283 $resp2 = mcrypt_generic($td, $this->challenge); 284 mcrypt_generic_deinit($td); 285 286 $key = $this->_desAddParity(substr($hash, 14, 7)); 287 mcrypt_generic_init($td, $key, $iv); 288 $resp3 = mcrypt_generic($td, $this->challenge); 289 mcrypt_generic_deinit($td); 290 mcrypt_module_close($td); 291 292 return $resp1 . $resp2 . $resp3; 293 } 294 295 /** 296 * Generates the LAN-Manager-HASH from the given plaintext password. 297 * 298 * @access public 299 * @return string 300 */ 301 function lmPasswordHash($password = null) 302 { 303 $plain = isset($password) ? $password : $this->password; 304 305 $plain = substr(strtoupper($plain), 0, 14); 306 while (strlen($plain) < 14) { 307 $plain .= "\0"; 308 } 309 310 return $this->_desHash(substr($plain, 0, 7)) . $this->_desHash(substr($plain, 7, 7)); 311 } 312 313 /** 314 * Generates an irreversible HASH. 315 * 316 * @access private 317 * @return string 318 */ 319 function _desHash($plain) 320 { 321 $key = $this->_desAddParity($plain); 322 $td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, ''); 323 $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); 324 mcrypt_generic_init($td, $key, $iv); 325 $hash = mcrypt_generic($td, 'KGS!@#$%'); 326 mcrypt_generic_deinit($td); 327 mcrypt_module_close($td); 328 return $hash; 329 } 330 331 /** 332 * Adds the parity bit to the given DES key. 333 * 334 * @access private 335 * @param string $key 7-Bytes Key without parity 336 * @return string 337 */ 338 function _desAddParity($key) 339 { 340 static $odd_parity = array( 341 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, 342 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, 343 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, 344 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, 345 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, 346 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, 347 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110, 348 112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127, 349 128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143, 350 145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158, 351 161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174, 352 176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191, 353 193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206, 354 208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223, 355 224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239, 356 241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254); 357 358 $bin = ''; 359 for ($i = 0; $i < strlen($key); $i++) { 360 $bin .= sprintf('%08s', decbin(ord($key{$i}))); 361 } 362 363 $str1 = explode('-', substr(chunk_split($bin, 7, '-'), 0, -1)); 364 $x = ''; 365 foreach($str1 as $s) { 366 $x .= sprintf('%02s', dechex($odd_parity[bindec($s . '0')])); 367 } 368 369 return pack('H*', $x); 370 371 } 372 373 /** 374 * Generates the response-packet. 375 * 376 * @param bool $lm wether including LAN-Manager-Response 377 * @access private 378 * @return string 379 */ 380 function response($lm = false) 381 { 382 $ntresp = $this->ntChallengeResponse(); 383 if ($lm) { 384 $lmresp = $this->lmChallengeResponse(); 385 } else { 386 $lmresp = str_repeat ("\0", 24); 387 } 388 389 // Response: LM Response, NT Response, flags (0 = use LM Response, 1 = use NT Response) 390 return $lmresp . $ntresp . pack('C', !$lm); 391 } 392 } 393 394 /** 395 * class Crypt_CHAP_MSv2 396 * 397 * Generate MS-CHAPv2 Packets. This version of MS-CHAP uses a 16 Bytes authenticator 398 * challenge and a 16 Bytes peer Challenge. LAN-Manager responses no longer exists 399 * in this version. The challenge is already a SHA1 challenge hash of both challenges 400 * and of the username. 401 * 402 * @package Crypt_CHAP 403 */ 404 class Crypt_CHAP_MSv2 extends Crypt_CHAP_MSv1 405 { 406 /** 407 * The username 408 * @var string 409 */ 410 var $username = null; 411 412 /** 413 * The 16 Bytes random binary peer challenge 414 * @var string 415 */ 416 var $peerChallenge = null; 417 418 /** 419 * The 16 Bytes random binary authenticator challenge 420 * @var string 421 */ 422 var $authChallenge = null; 423 424 /** 425 * Constructor 426 * 427 * Generates the 16 Bytes peer and authentication challenge 428 * @return void 429 */ 430 public function __construct() 431 { 432 parent::__construct(); 433 $this->generateChallenge('peerChallenge', 16); 434 $this->generateChallenge('authChallenge', 16); 435 } 436 437 /** 438 * Generates a hash from the NT-HASH. 439 * 440 * @access public 441 * @param string $nthash The NT-HASH 442 * @return string 443 */ 444 function ntPasswordHashHash($nthash) 445 { 446 return pack('H*',hash('md4', $nthash)); 447 } 448 449 /** 450 * Generates the challenge hash from the peer and the authenticator challenge and 451 * the username. SHA1 is used for this, but only the first 8 Bytes are used. 452 * 453 * @access public 454 * @return string 455 */ 456 function challengeHash() 457 { 458 return substr(pack('H*',hash('sha1', $this->peerChallenge . $this->authChallenge . $this->username)), 0, 8); 459 } 460 461 /** 462 * Generates the response. 463 * 464 * @access public 465 * @return string 466 */ 467 function challengeResponse() 468 { 469 $this->challenge = $this->challengeHash(); 470 return $this->_challengeResponse(); 471 } 472 } 473 474 475 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |