[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/pear/Auth/ -> RADIUS.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4: */
   3  /*
   4  Copyright (c) 2003, Michael Bretterklieber <michael@bretterklieber.com>
   5  All rights reserved.
   6  
   7  Redistribution and use in source and binary forms, with or without
   8  modification, are permitted provided that the following conditions
   9  are met:
  10  
  11  1. Redistributions of source code must retain the above copyright
  12     notice, this list of conditions and the following disclaimer.
  13  2. Redistributions in binary form must reproduce the above copyright
  14     notice, this list of conditions and the following disclaimer in the
  15     documentation and/or other materials provided with the distribution.
  16  3. The names of the authors may not be used to endorse or promote products
  17     derived from this software without specific prior written permission.
  18  
  19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  23  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  26  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  27  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  28  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29  
  30  This code cannot simply be copied and put under the GNU Public License or
  31  any other GPL-like (LGPL, GPL2) License.
  32  
  33      $Id$
  34  */
  35  
  36  require_once('PEAR.php');
  37  
  38  /**
  39   * Client implementation of RADIUS. This are wrapper classes for
  40   * the RADIUS PECL.
  41   * Provides RADIUS Authentication (RFC2865) and RADIUS Accounting (RFC2866).
  42   *
  43   * @package Auth_RADIUS
  44   * @author  Michael Bretterklieber <michael@bretterklieber.com>
  45   * @access  public
  46   * @version $Revision$
  47   */
  48  
  49  
  50  /**
  51   * class Auth_RADIUS
  52   *
  53   * Abstract base class for RADIUS
  54   *
  55   * @package Auth_RADIUS
  56   */
  57  class Auth_RADIUS extends PEAR {
  58  
  59      /**
  60       * List of RADIUS servers.
  61       * @var  array
  62       * @see  addServer(), putServer()
  63       */
  64      var $_servers  = array();
  65  
  66      /**
  67       * Path to the configuration-file.
  68       * @var  string
  69       * @see  setConfigFile()
  70       */
  71      var $_configfile = null;
  72  
  73      /**
  74       * Resource.
  75       * @var  resource
  76       * @see  open(), close()
  77       */
  78      var $res = null;
  79  
  80      /**
  81       * Username for authentication and accounting requests.
  82       * @var  string
  83       */
  84      var $username = null;
  85  
  86      /**
  87       * Password for plaintext-authentication (PAP).
  88       * @var  string
  89       */
  90      var $password = null;
  91  
  92      /**
  93       * List of known attributes.
  94       * @var  array
  95       * @see  dumpAttributes(), getAttributes()
  96       */
  97      var $attributes = array();
  98  
  99      /**
 100       * List of raw attributes.
 101       * @var  array
 102       * @see  dumpAttributes(), getAttributes()
 103       */
 104      var $rawAttributes = array();
 105  
 106      /**
 107       * List of raw vendor specific attributes.
 108       * @var  array
 109       * @see  dumpAttributes(), getAttributes()
 110       */
 111      var $rawVendorAttributes = array();
 112  
 113      /**
 114       * Switch whether we should put standard attributes or not
 115       * @var  bool
 116       * @see  putStandardAttributes()
 117       */
 118      var $useStandardAttributes = true;
 119  
 120      /**
 121       * Constructor
 122       *
 123       * Loads the RADIUS PECL/extension
 124       *
 125       * @return void
 126       */
 127      public function __construct()
 128      {
 129          $this->loadExtension('radius');
 130      }
 131  
 132      /**
 133       */
 134      public function loadExtension($ext) {
 135          if (extension_loaded($ext)) {
 136              return true;
 137          }
 138          // if either returns true dl() will produce a FATAL error, stop that
 139          if (
 140              function_exists('dl') === false ||
 141              ini_get('enable_dl') != 1 ||
 142              ini_get('safe_mode') == 1
 143          ) {
 144              return false;
 145          }
 146          if (OS_WINDOWS) {
 147              $suffix = '.dll';
 148          } elseif (PHP_OS == 'HP-UX') {
 149              $suffix = '.sl';
 150          } elseif (PHP_OS == 'AIX') {
 151              $suffix = '.a';
 152          } elseif (PHP_OS == 'OSX') {
 153              $suffix = '.bundle';
 154          } else {
 155              $suffix = '.so';
 156          }
 157          return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
 158      }
 159  
 160      /**
 161       * Adds a RADIUS server to the list of servers for requests.
 162       *
 163       * At most 10 servers may be specified.    When multiple servers
 164       * are given, they are tried in round-robin fashion until a
 165       * valid response is received
 166       *
 167       * @param  string  $servername   Servername or IP-Address
 168       * @param  integer $port         Portnumber
 169       * @param  string  $sharedSecret Shared secret
 170       * @param  integer $timeout      Timeout for each request
 171       * @param  integer $maxtries     Max. retries for each request
 172       * @return void
 173       */
 174      public function addServer($servername = 'localhost', $port = 0, $sharedSecret = 'testing123', $timeout = 3, $maxtries = 3)
 175      {
 176          $this->_servers[] = array($servername, $port, $sharedSecret, $timeout, $maxtries);
 177      }
 178  
 179      /**
 180       * Returns an error message, if an error occurred.
 181       *
 182       * @return string
 183       */
 184      public function getError()
 185      {
 186          return radius_strerror($this->res);
 187      }
 188  
 189      /**
 190       * Sets the configuration-file.
 191       *
 192       * @param  string  $file Path to the configuration file
 193       * @return void
 194       */
 195      public function setConfigfile($file)
 196      {
 197          $this->_configfile = $file;
 198      }
 199  
 200      /**
 201       * Puts an attribute.
 202       *
 203       * @param  integer $attrib       Attribute-number
 204       * @param  mixed   $port         Attribute-value
 205       * @param  type    $type         Attribute-type
 206       * @return bool  true on success, false on error
 207       */
 208      public function putAttribute($attrib, $value, $type = null)
 209      {
 210          if ($type == null) {
 211              $type = gettype($value);
 212          }
 213  
 214          switch ($type) {
 215              case 'integer':
 216              case 'double':
 217                  return radius_put_int($this->res, $attrib, $value);
 218  
 219              case 'addr':
 220                  return radius_put_addr($this->res, $attrib, $value);
 221  
 222              case 'string':
 223              default:
 224                  return radius_put_attr($this->res, $attrib, $value);
 225          }
 226  
 227      }
 228  
 229      /**
 230       * Puts a vendor-specific attribute.
 231       *
 232       * @param  integer $vendor       Vendor (MSoft, Cisco, ...)
 233       * @param  integer $attrib       Attribute-number
 234       * @param  mixed   $port         Attribute-value
 235       * @param  type    $type         Attribute-type
 236       * @return bool  true on success, false on error
 237       */
 238      public function putVendorAttribute($vendor, $attrib, $value, $type = null)
 239      {
 240  
 241          if ($type == null) {
 242              $type = gettype($value);
 243          }
 244  
 245          switch ($type) {
 246              case 'integer':
 247              case 'double':
 248                  return radius_put_vendor_int($this->res, $vendor, $attrib, $value);
 249  
 250              case 'addr':
 251                  return radius_put_vendor_addr($this->res, $vendor,$attrib, $value);
 252  
 253              case 'string':
 254              default:
 255                  return radius_put_vendor_attr($this->res, $vendor, $attrib, $value);
 256          }
 257  
 258      }
 259  
 260      /**
 261       * Prints known attributes received from the server.
 262       *
 263       */
 264      public function dumpAttributes()
 265      {
 266          foreach ($this->attributes as $name => $data) {
 267              echo "$name:$data<br>\n";
 268          }
 269      }
 270  
 271      /**
 272       * Overwrite this.
 273       */
 274      public function open()
 275      {
 276      }
 277  
 278      /**
 279       * Overwrite this.
 280       */
 281      public function createRequest()
 282      {
 283      }
 284  
 285      /**
 286       * Puts standard attributes.
 287       */
 288      public function putStandardAttributes()
 289      {
 290          if (!$this->useStandardAttributes) {
 291              return;
 292          }
 293  
 294          if (isset($_SERVER)) {
 295              $var = $_SERVER;
 296          } else {
 297              $var = $GLOBALS['HTTP_SERVER_VARS'];
 298          }
 299  
 300          $this->putAttribute(RADIUS_NAS_IDENTIFIER, isset($var['HTTP_HOST']) ? $var['HTTP_HOST'] : 'localhost');
 301          $this->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_VIRTUAL);
 302          $this->putAttribute(RADIUS_SERVICE_TYPE, RADIUS_FRAMED);
 303          $this->putAttribute(RADIUS_FRAMED_PROTOCOL, RADIUS_PPP);
 304          $this->putAttribute(RADIUS_CALLING_STATION_ID, isset($var['REMOTE_HOST']) ? $var['REMOTE_HOST'] : '127.0.0.1');
 305      }
 306  
 307      /**
 308       * Puts custom attributes.
 309       */
 310      public function putAuthAttributes()
 311      {
 312          if (isset($this->username)) {
 313              $this->putAttribute(RADIUS_USER_NAME, $this->username);
 314          }
 315      }
 316  
 317      /**
 318       * Configures the radius library.
 319       *
 320       * @param  string  $servername   Servername or IP-Address
 321       * @param  integer $port         Portnumber
 322       * @param  string  $sharedSecret Shared secret
 323       * @param  integer $timeout      Timeout for each request
 324       * @param  integer $maxtries     Max. retries for each request
 325       * @return bool  true on success, false on error
 326       * @see addServer()
 327       */
 328      public function putServer($servername, $port = 0, $sharedsecret = 'testing123', $timeout = 3, $maxtries = 3)
 329      {
 330          if (!radius_add_server($this->res, $servername, $port, $sharedsecret, $timeout, $maxtries)) {
 331              return false;
 332          }
 333          return true;
 334      }
 335  
 336      /**
 337       * Configures the radius library via external configurationfile
 338       *
 339       * @param  string  $servername   Servername or IP-Address
 340       * @return bool  true on success, false on error
 341       */
 342      public function putConfigfile($file)
 343      {
 344          if (!radius_config($this->res, $file)) {
 345              return false;
 346          }
 347          return true;
 348      }
 349  
 350      /**
 351       * Initiates a RADIUS request.
 352       *
 353       * @return bool  true on success, false on errors
 354       */
 355      public function start()
 356      {
 357          if (!$this->open()) {
 358              return false;
 359          }
 360  
 361          foreach ($this->_servers as $s) {
 362              // Servername, port, sharedsecret, timeout, retries
 363              if (!$this->putServer($s[0], $s[1], $s[2], $s[3], $s[4])) {
 364                  return false;
 365              }
 366          }
 367  
 368          if (!empty($this->_configfile)) {
 369              if (!$this->putConfigfile($this->_configfile)) {
 370                  return false;
 371              }
 372          }
 373  
 374          $this->createRequest();
 375          $this->putStandardAttributes();
 376          $this->putAuthAttributes();
 377          return true;
 378      }
 379  
 380      /**
 381       * Sends a prepared RADIUS request and waits for a response
 382       *
 383       * @return mixed  true on success, false on reject, PEAR_Error on error
 384       */
 385      public function send()
 386      {
 387          $req = radius_send_request($this->res);
 388          if (!$req) {
 389              throw new Auth_RADIUS_Exception('Error sending request: ' . $this->getError());
 390          }
 391  
 392          switch($req) {
 393              case RADIUS_ACCESS_ACCEPT:
 394                  if (is_subclass_of($this, 'auth_radius_acct')) {
 395                      throw new Auth_RADIUS_Exception('RADIUS_ACCESS_ACCEPT is unexpected for accounting');
 396                  }
 397                  return true;
 398  
 399              case RADIUS_ACCESS_REJECT:
 400                  return false;
 401  
 402              case RADIUS_ACCOUNTING_RESPONSE:
 403                  if (is_subclass_of($this, 'auth_radius_pap')) {
 404                      throw new Auth_RADIUS_Exception('RADIUS_ACCOUNTING_RESPONSE is unexpected for authentication');
 405                  }
 406                  return true;
 407  
 408              default:
 409                  throw new Auth_RADIUS_Exception("Unexpected return value: $req");
 410          }
 411  
 412      }
 413  
 414      /**
 415       * Reads all received attributes after sending the request.
 416       *
 417       * This methods stores known attributes in the property attributes,
 418       * all attributes (including known attibutes) are stored in rawAttributes
 419       * or rawVendorAttributes.
 420       * NOTE: call this function also even if the request was rejected, because the
 421       * Server returns usualy an errormessage
 422       *
 423       * @return bool   true on success, false on error
 424       */
 425      public function getAttributes()
 426      {
 427  
 428          while ($attrib = radius_get_attr($this->res)) {
 429  
 430              if (!is_array($attrib)) {
 431                  return false;
 432              }
 433  
 434              $attr = $attrib['attr'];
 435              $data = $attrib['data'];
 436  
 437              $this->rawAttributes[$attr] = $data;
 438  
 439              switch ($attr) {
 440                  case RADIUS_FRAMED_IP_ADDRESS:
 441                      $this->attributes['framed_ip'] = radius_cvt_addr($data);
 442                      break;
 443  
 444                  case RADIUS_FRAMED_IP_NETMASK:
 445                      $this->attributes['framed_mask'] = radius_cvt_addr($data);
 446                      break;
 447  
 448                  case RADIUS_FRAMED_MTU:
 449                      $this->attributes['framed_mtu'] = radius_cvt_int($data);
 450                      break;
 451  
 452                  case RADIUS_FRAMED_COMPRESSION:
 453                      $this->attributes['framed_compression'] = radius_cvt_int($data);
 454                      break;
 455  
 456                  case RADIUS_SESSION_TIMEOUT:
 457                      $this->attributes['session_timeout'] = radius_cvt_int($data);
 458                      break;
 459  
 460                  case RADIUS_IDLE_TIMEOUT:
 461                      $this->attributes['idle_timeout'] = radius_cvt_int($data);
 462                      break;
 463  
 464                  case RADIUS_SERVICE_TYPE:
 465                      $this->attributes['service_type'] = radius_cvt_int($data);
 466                      break;
 467  
 468                  case RADIUS_CLASS:
 469                      $this->attributes['class'] = radius_cvt_string($data);
 470                      break;
 471  
 472                  case RADIUS_FRAMED_PROTOCOL:
 473                      $this->attributes['framed_protocol'] = radius_cvt_int($data);
 474                      break;
 475  
 476                  case RADIUS_FRAMED_ROUTING:
 477                      $this->attributes['framed_routing'] = radius_cvt_int($data);
 478                      break;
 479  
 480                  case RADIUS_FILTER_ID:
 481                      $this->attributes['filter_id'] = radius_cvt_string($data);
 482                      break;
 483  
 484                  case RADIUS_REPLY_MESSAGE:
 485                      $this->attributes['reply_message'] = radius_cvt_string($data);
 486                      break;
 487  
 488                  case RADIUS_VENDOR_SPECIFIC:
 489                      $attribv = radius_get_vendor_attr($data);
 490                      if (!is_array($attribv)) {
 491                          return false;
 492                      }
 493  
 494                      $vendor = $attribv['vendor'];
 495                      $attrv = $attribv['attr'];
 496                      $datav = $attribv['data'];
 497  
 498                      $this->rawVendorAttributes[$vendor][$attrv] = $datav;
 499  
 500                      if ($vendor == RADIUS_VENDOR_MICROSOFT) {
 501  
 502                          switch ($attrv) {
 503                              case RADIUS_MICROSOFT_MS_CHAP2_SUCCESS:
 504                                  $this->attributes['ms_chap2_success'] = radius_cvt_string($datav);
 505                                  break;
 506  
 507                              case RADIUS_MICROSOFT_MS_CHAP_ERROR:
 508                                  $this->attributes['ms_chap_error'] = radius_cvt_string(substr($datav,1));
 509                                  break;
 510  
 511                              case RADIUS_MICROSOFT_MS_CHAP_DOMAIN:
 512                                  $this->attributes['ms_chap_domain'] = radius_cvt_string($datav);
 513                                  break;
 514  
 515                              case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
 516                                  $this->attributes['ms_mppe_encryption_policy'] = radius_cvt_int($datav);
 517                                  break;
 518  
 519                              case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
 520                                  $this->attributes['ms_mppe_encryption_types'] = radius_cvt_int($datav);
 521                                  break;
 522  
 523                              case RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS:
 524                                  $demangled = radius_demangle($this->res, $datav);
 525                                  $this->attributes['ms_chap_mppe_lm_key'] = substr($demangled, 0, 8);
 526                                  $this->attributes['ms_chap_mppe_nt_key'] = substr($demangled, 8, RADIUS_MPPE_KEY_LEN);
 527                                  break;
 528  
 529                              case RADIUS_MICROSOFT_MS_MPPE_SEND_KEY:
 530                                  $this->attributes['ms_chap_mppe_send_key'] = radius_demangle_mppe_key($this->res, $datav);
 531                                  break;
 532  
 533                              case RADIUS_MICROSOFT_MS_MPPE_RECV_KEY:
 534                                  $this->attributes['ms_chap_mppe_recv_key'] = radius_demangle_mppe_key($this->res, $datav);
 535                                  break;
 536  
 537                              case RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER:
 538                                  $this->attributes['ms_primary_dns_server'] = radius_cvt_string($datav);
 539                                  break;
 540                          }
 541                      }
 542                      break;
 543  
 544              }
 545          }
 546  
 547          return true;
 548      }
 549  
 550      /**
 551       * Frees resources.
 552       *
 553       * Calling this method is always a good idea, because all security relevant
 554       * attributes are filled with Nullbytes to leave nothing in the mem.
 555       *
 556       */
 557      public function close()
 558      {
 559          if ($this->res != null) {
 560              radius_close($this->res);
 561              $this->res = null;
 562          }
 563          $this->username = str_repeat("\0", strlen($this->username));
 564          $this->password = str_repeat("\0", strlen($this->password));
 565      }
 566  
 567  }
 568  
 569  /**
 570   * class Auth_RADIUS_PAP
 571   *
 572   * Class for authenticating using PAP (Plaintext)
 573   *
 574   * @package Auth_RADIUS
 575   */
 576  class Auth_RADIUS_PAP extends Auth_RADIUS
 577  {
 578  
 579      /**
 580       * Constructor
 581       *
 582       * @param  string  $username   Username
 583       * @param  string  $password   Password
 584       * @return void
 585       */
 586      public function __construct($username = null, $password = null)
 587      {
 588          parent::__construct();
 589          $this->username = $username;
 590          $this->password = $password;
 591      }
 592  
 593      /**
 594       * Creates a RADIUS resource
 595       *
 596       * Creates a RADIUS resource for authentication. This should be the first
 597       * call before you make any other things with the library.
 598       *
 599       * @return bool   true on success, false on error
 600       */
 601      function open()
 602      {
 603          $this->res = radius_auth_open();
 604          if (!$this->res) {
 605              return false;
 606          }
 607          return true;
 608      }
 609  
 610      /**
 611       * Creates an authentication request
 612       *
 613       * Creates an authentication request.
 614       * You MUST call this method before you can put any attribute
 615       *
 616       * @return bool   true on success, false on error
 617       */
 618      function createRequest()
 619      {
 620          if (!radius_create_request($this->res, RADIUS_ACCESS_REQUEST)) {
 621              return false;
 622          }
 623          return true;
 624      }
 625  
 626      /**
 627       * Put authentication specific attributes
 628       *
 629       * @return void
 630       */
 631      function putAuthAttributes()
 632      {
 633          if (isset($this->username)) {
 634              $this->putAttribute(RADIUS_USER_NAME, $this->username);
 635          }
 636          if (isset($this->password)) {
 637              $this->putAttribute(RADIUS_USER_PASSWORD, $this->password);
 638          }
 639      }
 640  
 641  }
 642  
 643  /**
 644   * class Auth_RADIUS_CHAP_MD5
 645   *
 646   * Class for authenticating using CHAP-MD5 see RFC1994.
 647   * Instead og the plaintext password the challenge and
 648   * the response are needed.
 649   *
 650   * @package Auth_RADIUS
 651   */
 652  class Auth_RADIUS_CHAP_MD5 extends Auth_RADIUS_PAP
 653  {
 654      /**
 655       * 8 Bytes binary challenge
 656       * @var  string
 657       */
 658      var $challenge = null;
 659  
 660      /**
 661       * 16 Bytes MD5 response binary
 662       * @var  string
 663       */
 664      var $response = null;
 665  
 666      /**
 667       * Id of the authentication request. Should incremented after every request.
 668       * @var  integer
 669       */
 670      var $chapid = 1;
 671  
 672      /**
 673       * Constructor
 674       *
 675       * @param  string  $username   Username
 676       * @param  string  $challenge  8 Bytes Challenge (binary)
 677       * @param  integer $chapid     Requestnumber
 678       * @return void
 679       */
 680      function __construct($username = null, $challenge = null, $chapid = 1)
 681      {
 682          parent::__construct();
 683          $this->username = $username;
 684          $this->challenge = $challenge;
 685          $this->chapid = $chapid;
 686      }
 687  
 688      /**
 689       * Put CHAP-MD5 specific attributes
 690       *
 691       * For authenticating using CHAP-MD5 via RADIUS you have to put the challenge
 692       * and the response. The chapid is inserted in the first byte of the response.
 693       *
 694       * @return void
 695       */
 696      function putAuthAttributes()
 697      {
 698          if (isset($this->username)) {
 699              $this->putAttribute(RADIUS_USER_NAME, $this->username);
 700          }
 701          if (isset($this->response)) {
 702              $response = pack('C', $this->chapid) . $this->response;
 703              $this->putAttribute(RADIUS_CHAP_PASSWORD, $response);
 704          }
 705          if (isset($this->challenge)) {
 706              $this->putAttribute(RADIUS_CHAP_CHALLENGE, $this->challenge);
 707          }
 708      }
 709  
 710      /**
 711       * Frees resources.
 712       *
 713       * Calling this method is always a good idea, because all security relevant
 714       * attributes are filled with Nullbytes to leave nothing in the mem.
 715       */
 716      public function close()
 717      {
 718          parent::close();
 719          $this->challenge =  str_repeat("\0", strlen($this->challenge));
 720          $this->response =  str_repeat("\0", strlen($this->response));
 721      }
 722  
 723  }
 724  
 725  /**
 726   * class Auth_RADIUS_MSCHAPv1
 727   *
 728   * Class for authenticating using MS-CHAPv1 see RFC2433
 729   *
 730   * @package Auth_RADIUS
 731   */
 732  class Auth_RADIUS_MSCHAPv1 extends Auth_RADIUS_CHAP_MD5
 733  {
 734      /**
 735       * LAN-Manager-Response
 736       * @var  string
 737       */
 738      var $lmResponse = null;
 739  
 740      /**
 741       * Wether using deprecated LM-Responses or not.
 742       * 0 = use LM-Response, 1 = use NT-Response
 743       * @var  bool
 744       */
 745      var $flags = 1;
 746  
 747      /**
 748       * Put MS-CHAPv1 specific attributes
 749       *
 750       * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge
 751       * and the response. The response has this structure:
 752       * struct rad_mschapvalue {
 753       *   u_char ident;
 754       *   u_char flags;
 755       *   u_char lm_response[24];
 756       *   u_char response[24];
 757       * };
 758       *
 759       * @return void
 760       */
 761      function putAuthAttributes()
 762      {
 763          if (isset($this->username)) {
 764              $this->putAttribute(RADIUS_USER_NAME, $this->username);
 765          }
 766          if (isset($this->response) || isset($this->lmResponse)) {
 767              $lmResp = isset($this->lmResponse) ? $this->lmResponse : str_repeat ("\0", 24);
 768              $ntResp = isset($this->response)   ? $this->response :   str_repeat ("\0", 24);
 769              $resp = pack('CC', $this->chapid, $this->flags) . $lmResp . $ntResp;
 770              $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_RESPONSE, $resp);
 771          }
 772          if (isset($this->challenge)) {
 773              $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
 774          }
 775      }
 776  }
 777  
 778  /**
 779   * class Auth_RADIUS_MSCHAPv2
 780   *
 781   * Class for authenticating using MS-CHAPv2 see RFC2759
 782   *
 783   * @package Auth_RADIUS
 784   */
 785  class Auth_RADIUS_MSCHAPv2 extends Auth_RADIUS_MSCHAPv1
 786  {
 787      /**
 788       * 16 Bytes binary challenge
 789       * @var  string
 790       */
 791      var $challenge = null;
 792  
 793      /**
 794       * 16 Bytes binary Peer Challenge
 795       * @var  string
 796       */
 797      var $peerChallenge = null;
 798  
 799      /**
 800       * Put MS-CHAPv2 specific attributes
 801       *
 802       * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge
 803       * and the response. The response has this structure:
 804       * struct rad_mschapv2value {
 805       *   u_char ident;
 806       *   u_char flags;
 807       *   u_char pchallenge[16];
 808       *   u_char reserved[8];
 809       *   u_char response[24];
 810       * };
 811       * where pchallenge is the peer challenge. Like for MS-CHAPv1 we set the flags field to 1.
 812       * @return void
 813       */
 814      function putAuthAttributes()
 815      {
 816          if (isset($this->username)) {
 817              $this->putAttribute(RADIUS_USER_NAME, $this->username);
 818          }
 819          if (isset($this->response) && isset($this->peerChallenge)) {
 820              // Response: chapid, flags (1 = use NT Response), Peer challenge, reserved, Response
 821              $resp = pack('CCa16a8a24',$this->chapid , 1, $this->peerChallenge, str_repeat("\0", 8), $this->response);
 822              $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP2_RESPONSE, $resp);
 823          }
 824          if (isset($this->challenge)) {
 825              $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
 826          }
 827      }
 828  
 829      /**
 830       * Frees resources.
 831       *
 832       * Calling this method is always a good idea, because all security relevant
 833       * attributes are filled with Nullbytes to leave nothing in the mem.
 834       *
 835       * @access public
 836       */
 837      function close()
 838      {
 839          parent::close();
 840          $this->peerChallenge = str_repeat("\0", strlen($this->peerChallenge));
 841      }
 842  }
 843  
 844  /**
 845   * class Auth_RADIUS_Acct
 846   *
 847   * Class for RADIUS accounting
 848   *
 849   * @package Auth_RADIUS
 850   */
 851  class Auth_RADIUS_Acct extends Auth_RADIUS
 852  {
 853      /**
 854       * Defines where the Authentication was made, possible values are:
 855       * RADIUS_AUTH_RADIUS, RADIUS_AUTH_LOCAL, RADIUS_AUTH_REMOTE
 856       * @var  integer
 857       */
 858      var $authentic = null;
 859  
 860      /**
 861       * Defines the type of the accounting request, on of:
 862       * RADIUS_START, RADIUS_STOP, RADIUS_ACCOUNTING_ON, RADIUS_ACCOUNTING_OFF
 863       * @var  integer
 864       */
 865      var $status_type = null;
 866  
 867      /**
 868       * The time the user was logged in in seconds
 869       * @var  integer
 870       */
 871      var $session_time = null;
 872  
 873      /**
 874       * A uniq identifier for the session of the user, maybe the PHP-Session-Id
 875       * @var  string
 876       */
 877      var $session_id = null;
 878  
 879      /**
 880       * Constructor
 881       *
 882       * Generates a predefined session_id. We use the Remote-Address, the PID, and the Current user.
 883       * @return void
 884       */
 885      function __construct()
 886      {
 887          parent::__construct();
 888  
 889          if (isset($_SERVER)) {
 890              $var = $_SERVER;
 891          } else {
 892              $var = $GLOBALS['HTTP_SERVER_VARS'];
 893          }
 894  
 895          $this->session_id = sprintf("%s:%d-%s", isset($var['REMOTE_ADDR']) ? $var['REMOTE_ADDR'] : '127.0.0.1' , getmypid(), get_current_user());
 896      }
 897  
 898      /**
 899       * Creates a RADIUS resource
 900       *
 901       * Creates a RADIUS resource for accounting. This should be the first
 902       * call before you make any other things with the library.
 903       *
 904       * @return bool   true on success, false on error
 905       */
 906      function open()
 907      {
 908          $this->res = radius_acct_open();
 909          if (!$this->res) {
 910              return false;
 911          }
 912          return true;
 913      }
 914  
 915      /**
 916       * Creates an accounting request
 917       *
 918       * Creates an accounting request.
 919       * You MUST call this method before you can put any attribute.
 920       *
 921       * @return bool   true on success, false on error
 922       */
 923      function createRequest()
 924      {
 925          if (!radius_create_request($this->res, RADIUS_ACCOUNTING_REQUEST)) {
 926              return false;
 927          }
 928          return true;
 929      }
 930  
 931      /**
 932       * Put attributes for accounting.
 933       *
 934       * Here we put some accounting values. There many more attributes for accounting,
 935       * but for web-applications only certain attributes make sense.
 936       * @return void
 937       */
 938      function putAuthAttributes()
 939      {
 940          $this->putAttribute(RADIUS_ACCT_SESSION_ID, $this->session_id);
 941          $this->putAttribute(RADIUS_ACCT_STATUS_TYPE, $this->status_type);
 942          if (isset($this->session_time) && $this->status_type == RADIUS_STOP) {
 943              $this->putAttribute(RADIUS_ACCT_SESSION_TIME, $this->session_time);
 944          }
 945          if (isset($this->authentic)) {
 946              $this->putAttribute(RADIUS_ACCT_AUTHENTIC, $this->authentic);
 947          }
 948  
 949      }
 950  
 951  }
 952  
 953  /**
 954   * class Auth_RADIUS_Acct_Start
 955   *
 956   * Class for RADIUS accounting. Its usualy used, after the user has logged in.
 957   *
 958   * @package Auth_RADIUS
 959   */
 960  class Auth_RADIUS_Acct_Start extends Auth_RADIUS_Acct
 961  {
 962      /**
 963       * Defines the type of the accounting request.
 964       * It is set to RADIUS_START by default in this class.
 965       * @var  integer
 966       */
 967      var $status_type = RADIUS_START;
 968  }
 969  
 970  /**
 971   * class Auth_RADIUS_Acct_Start
 972   *
 973   * Class for RADIUS accounting. Its usualy used, after the user has logged out.
 974   *
 975   * @package Auth_RADIUS
 976   */
 977  class Auth_RADIUS_Acct_Stop extends Auth_RADIUS_Acct
 978  {
 979      /**
 980       * Defines the type of the accounting request.
 981       * It is set to RADIUS_STOP by default in this class.
 982       * @var  integer
 983       */
 984      var $status_type = RADIUS_STOP;
 985  }
 986  
 987  if (!defined('RADIUS_UPDATE')) {
 988      define('RADIUS_UPDATE', 3);
 989  }
 990  
 991  /**
 992   * class Auth_RADIUS_Acct_Update
 993   *
 994   * Class for interim RADIUS accounting updates.
 995   *
 996   * @package Auth_RADIUS
 997   */
 998  class Auth_RADIUS_Acct_Update extends Auth_RADIUS_Acct
 999  {
1000      /**
1001       * Defines the type of the accounting request.
1002       * It is set to RADIUS_UPDATE by default in this class.
1003       * @var  integer
1004       */
1005      var $status_type = RADIUS_UPDATE;
1006  }
1007  
1008  class Auth_RADIUS_Exception extends Exception {}


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1