[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/pear/Crypt/ -> CHAP.php (source)

   1  <?php
   2  /*
   3  Copyright (c) 2002-2010, Michael Bretterklieber <[email protected]>
   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 <[email protected]>
  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      function Crypt_CHAP()
  89      {
  90          $this->PEAR();
  91          $this->generateChallenge();
  92      }
  93  
  94      /**
  95       * Generates a random binary challenge
  96       *
  97       * @param  string  $varname  Name of the property
  98       * @param  integer $size     Size of the challenge in Bytes
  99       * @return void
 100       */
 101      function generateChallenge($varname = 'challenge', $size = 8)
 102      {
 103          $this->$varname = '';
 104          for ($i = 0; $i < $size; $i++) {
 105              $this->$varname .= pack('C', 1 + mt_rand() % 255);
 106          }
 107          return $this->$varname;
 108      }
 109  
 110      /**
 111       * Generates the response. Overwrite this.
 112       *
 113       * @return void
 114       */
 115      function challengeResponse()
 116      {
 117      }
 118  
 119  }
 120  
 121  /**
 122   * class Crypt_CHAP_MD5
 123   *
 124   * Generate CHAP-MD5 Packets
 125   *
 126   * @package Crypt_CHAP
 127   */
 128  class Crypt_CHAP_MD5 extends Crypt_CHAP
 129  {
 130  
 131      /**
 132       * Generates the response.
 133       *
 134       * CHAP-MD5 uses MD5-Hash for generating the response. The Hash consists
 135       * of the chapid, the plaintext password and the challenge.
 136       *
 137       * @return string
 138       */
 139      function challengeResponse()
 140      {
 141          return pack('H*', md5(pack('C', $this->chapid) . $this->password . $this->challenge));
 142      }
 143  }
 144  
 145  /**
 146   * class Crypt_CHAP_MSv1
 147   *
 148   * Generate MS-CHAPv1 Packets. MS-CHAP doesen't use the plaintext password, it uses the
 149   * NT-HASH wich is stored in the SAM-Database or in the smbpasswd, if you are using samba.
 150   * The NT-HASH is MD4(str2unicode(plaintextpass)).
 151   * You need the hash extension for this class.
 152   *
 153   * @package Crypt_CHAP
 154   */
 155  class Crypt_CHAP_MSv1 extends Crypt_CHAP
 156  {
 157      /**
 158       * Wether using deprecated LM-Responses or not.
 159       * 0 = use LM-Response, 1 = use NT-Response
 160       * @var  bool
 161       */
 162      var $flags = 1;
 163  
 164      /**
 165       * Constructor
 166       *
 167       * Loads the hash extension
 168       * @return void
 169       */
 170      function Crypt_CHAP_MSv1()
 171      {
 172          $this->Crypt_CHAP();
 173          $this->loadExtension('hash');
 174      }
 175  
 176      /**
 177       * Generates the NT-HASH from the given plaintext password.
 178       *
 179       * @access public
 180       * @return string
 181       */
 182      function ntPasswordHash($password = null)
 183      {
 184          if (isset($password)) {
 185              return pack('H*',hash('md4', $this->str2unicode($password)));
 186          } else {
 187              return pack('H*',hash('md4', $this->str2unicode($this->password)));
 188          }
 189      }
 190  
 191      /**
 192       * Converts ascii to unicode.
 193       *
 194       * @access public
 195       * @return string
 196       */
 197      function str2unicode($str)
 198      {
 199          $uni = '';
 200          $str = (string) $str;
 201          for ($i = 0; $i < strlen($str); $i++) {
 202              $a = ord($str{$i}) << 8;
 203              $uni .= sprintf("%X", $a);
 204          }
 205          return pack('H*', $uni);
 206      }
 207  
 208      /**
 209       * Generates the NT-Response.
 210       *
 211       * @access public
 212       * @return string
 213       */
 214      function challengeResponse()
 215      {
 216          return $this->_challengeResponse();
 217      }
 218  
 219      /**
 220       * Generates the NT-Response.
 221       *
 222       * @access public
 223       * @return string
 224       */
 225      function ntChallengeResponse()
 226      {
 227          return $this->_challengeResponse(false);
 228      }
 229  
 230      /**
 231       * Generates the LAN-Manager-Response.
 232       *
 233       * @access public
 234       * @return string
 235       */
 236      function lmChallengeResponse()
 237      {
 238          return $this->_challengeResponse(true);
 239      }
 240  
 241      /**
 242       * Generates the response.
 243       *
 244       * Generates the response using DES.
 245       *
 246       * @param  bool  $lm  wether generating LAN-Manager-Response
 247       * @access private
 248       * @return string
 249       */
 250      function _challengeResponse($lm = false)
 251      {
 252          if ($lm) {
 253              $hash = $this->lmPasswordHash();
 254          } else {
 255              $hash = $this->ntPasswordHash();
 256          }
 257  
 258          while (strlen($hash) < 21) {
 259              $hash .= "\0";
 260          }
 261  
 262          $td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
 263          $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
 264          $key = $this->_desAddParity(substr($hash, 0, 7));
 265          mcrypt_generic_init($td, $key, $iv);
 266          $resp1 = mcrypt_generic($td, $this->challenge);
 267          mcrypt_generic_deinit($td);
 268  
 269          $key = $this->_desAddParity(substr($hash, 7, 7));
 270          mcrypt_generic_init($td, $key, $iv);
 271          $resp2 = mcrypt_generic($td, $this->challenge);
 272          mcrypt_generic_deinit($td);
 273  
 274          $key = $this->_desAddParity(substr($hash, 14, 7));
 275          mcrypt_generic_init($td, $key, $iv);
 276          $resp3 = mcrypt_generic($td, $this->challenge);
 277          mcrypt_generic_deinit($td);
 278          mcrypt_module_close($td);
 279  
 280          return $resp1 . $resp2 . $resp3;
 281      }
 282  
 283      /**
 284       * Generates the LAN-Manager-HASH from the given plaintext password.
 285       *
 286       * @access public
 287       * @return string
 288       */
 289      function lmPasswordHash($password = null)
 290      {
 291          $plain = isset($password) ? $password : $this->password;
 292  
 293          $plain = substr(strtoupper($plain), 0, 14);
 294          while (strlen($plain) < 14) {
 295               $plain .= "\0";
 296          }
 297  
 298          return $this->_desHash(substr($plain, 0, 7)) . $this->_desHash(substr($plain, 7, 7));
 299      }
 300  
 301      /**
 302       * Generates an irreversible HASH.
 303       *
 304       * @access private
 305       * @return string
 306       */
 307      function _desHash($plain)
 308      {
 309          $key = $this->_desAddParity($plain);
 310          $td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
 311          $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
 312          mcrypt_generic_init($td, $key, $iv);
 313          $hash = mcrypt_generic($td, 'KGS!@#$%');
 314          mcrypt_generic_deinit($td);
 315          mcrypt_module_close($td);
 316          return $hash;
 317      }
 318  
 319      /**
 320       * Adds the parity bit to the given DES key.
 321       *
 322       * @access private
 323       * @param  string  $key 7-Bytes Key without parity
 324       * @return string
 325       */
 326      function _desAddParity($key)
 327      {
 328          static $odd_parity = array(
 329                  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
 330                  16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
 331                  32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
 332                  49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
 333                  64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
 334                  81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
 335                  97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
 336                  112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
 337                  128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
 338                  145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
 339                  161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
 340                  176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
 341                  193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
 342                  208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
 343                  224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
 344                  241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254);
 345  
 346          $bin = '';
 347          for ($i = 0; $i < strlen($key); $i++) {
 348              $bin .= sprintf('%08s', decbin(ord($key{$i})));
 349          }
 350  
 351          $str1 = explode('-', substr(chunk_split($bin, 7, '-'), 0, -1));
 352          $x = '';
 353          foreach($str1 as $s) {
 354              $x .= sprintf('%02s', dechex($odd_parity[bindec($s . '0')]));
 355          }
 356  
 357          return pack('H*', $x);
 358  
 359      }
 360  
 361      /**
 362       * Generates the response-packet.
 363       *
 364       * @param  bool  $lm  wether including LAN-Manager-Response
 365       * @access private
 366       * @return string
 367       */
 368      function response($lm = false)
 369      {
 370          $ntresp = $this->ntChallengeResponse();
 371          if ($lm) {
 372              $lmresp = $this->lmChallengeResponse();
 373          } else {
 374              $lmresp = str_repeat ("\0", 24);
 375          }
 376  
 377          // Response: LM Response, NT Response, flags (0 = use LM Response, 1 = use NT Response)
 378          return $lmresp . $ntresp . pack('C', !$lm);
 379      }
 380  }
 381  
 382  /**
 383   * class Crypt_CHAP_MSv2
 384   *
 385   * Generate MS-CHAPv2 Packets. This version of MS-CHAP uses a 16 Bytes authenticator
 386   * challenge and a 16 Bytes peer Challenge. LAN-Manager responses no longer exists
 387   * in this version. The challenge is already a SHA1 challenge hash of both challenges
 388   * and of the username.
 389   *
 390   * @package Crypt_CHAP
 391   */
 392  class Crypt_CHAP_MSv2 extends Crypt_CHAP_MSv1
 393  {
 394      /**
 395       * The username
 396       * @var  string
 397       */
 398      var $username = null;
 399  
 400      /**
 401       * The 16 Bytes random binary peer challenge
 402       * @var  string
 403       */
 404      var $peerChallenge = null;
 405  
 406      /**
 407       * The 16 Bytes random binary authenticator challenge
 408       * @var  string
 409       */
 410      var $authChallenge = null;
 411  
 412      /**
 413       * Constructor
 414       *
 415       * Generates the 16 Bytes peer and authentication challenge
 416       * @return void
 417       */
 418      function Crypt_CHAP_MSv2()
 419      {
 420          $this->Crypt_CHAP_MSv1();
 421          $this->generateChallenge('peerChallenge', 16);
 422          $this->generateChallenge('authChallenge', 16);
 423      }
 424  
 425      /**
 426       * Generates a hash from the NT-HASH.
 427       *
 428       * @access public
 429       * @param  string  $nthash The NT-HASH
 430       * @return string
 431       */
 432      function ntPasswordHashHash($nthash)
 433      {
 434          return pack('H*',hash('md4', $nthash));
 435      }
 436  
 437      /**
 438       * Generates the challenge hash from the peer and the authenticator challenge and
 439       * the username. SHA1 is used for this, but only the first 8 Bytes are used.
 440       *
 441       * @access public
 442       * @return string
 443       */
 444      function challengeHash()
 445      {
 446          return substr(pack('H*',hash('sha1', $this->peerChallenge . $this->authChallenge . $this->username)), 0, 8);
 447      }
 448  
 449      /**
 450       * Generates the response.
 451       *
 452       * @access public
 453       * @return string
 454       */
 455      function challengeResponse()
 456      {
 457          $this->challenge = $this->challengeHash();
 458          return $this->_challengeResponse();
 459      }
 460  }
 461  
 462  
 463  ?>


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1