Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/pear/Auth/RADIUS.php
Go to the documentation of this file.
00001 <?php
00002 /* vim: set expandtab tabstop=4 shiftwidth=4: */
00003 /*
00004 Copyright (c) 2003, Michael Bretterklieber <michael@bretterklieber.com>
00005 All rights reserved.
00006 
00007 Redistribution and use in source and binary forms, with or without
00008 modification, are permitted provided that the following conditions
00009 are met:
00010 
00011 1. Redistributions of source code must retain the above copyright
00012    notice, this list of conditions and the following disclaimer.
00013 2. Redistributions in binary form must reproduce the above copyright
00014    notice, this list of conditions and the following disclaimer in the
00015    documentation and/or other materials provided with the distribution.
00016 3. The names of the authors may not be used to endorse or promote products
00017    derived from this software without specific prior written permission.
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00020 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00022 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00023 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00024 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00025 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00026 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00027 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00028 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 
00030 This code cannot simply be copied and put under the GNU Public License or
00031 any other GPL-like (LGPL, GPL2) License.
00032 
00033     $Id: RADIUS.php,v 1.2 2010/12/14 17:36:06 moodlerobot Exp $
00034 */
00035 
00036 require_once 'PEAR.php';
00037 
00049 PEAR::loadExtension('radius');
00050 
00058 class Auth_RADIUS extends PEAR {
00059 
00065     var $_servers  = array();
00066 
00072     var $_configfile = null;
00073 
00079     var $res = null;
00080 
00085     var $username = null;
00086 
00091     var $password = null;
00092 
00098     var $attributes = array();
00099 
00105     var $rawAttributes = array();
00106 
00112     var $rawVendorAttributes = array();
00113 
00119     var $useStandardAttributes = true;
00120 
00128     function Auth_RADIUS()
00129     {
00130         $this->PEAR();
00131     }
00132 
00148     function addServer($servername = 'localhost', $port = 0, $sharedSecret = 'testing123', $timeout = 3, $maxtries = 3)
00149     {
00150         $this->_servers[] = array($servername, $port, $sharedSecret, $timeout, $maxtries);
00151     }
00152 
00159     function getError()
00160     {
00161         return radius_strerror($this->res);
00162     }
00163 
00171     function setConfigfile($file)
00172     {
00173         $this->_configfile = $file;
00174     }
00175 
00185     function putAttribute($attrib, $value, $type = null)
00186     {
00187         if ($type == null) {
00188             $type = gettype($value);
00189         }
00190 
00191         switch ($type) {
00192         case 'integer':
00193         case 'double':
00194             return radius_put_int($this->res, $attrib, $value);
00195 
00196         case 'addr':
00197             return radius_put_addr($this->res, $attrib, $value);
00198 
00199         case 'string':
00200         default:
00201             return radius_put_attr($this->res, $attrib, $value);
00202         }
00203 
00204     }
00205 
00216     function putVendorAttribute($vendor, $attrib, $value, $type = null)
00217     {
00218 
00219         if ($type == null) {
00220             $type = gettype($value);
00221         }
00222 
00223         switch ($type) {
00224         case 'integer':
00225         case 'double':
00226             return radius_put_vendor_int($this->res, $vendor, $attrib, $value);
00227 
00228         case 'addr':
00229             return radius_put_vendor_addr($this->res, $vendor,$attrib, $value);
00230 
00231         case 'string':
00232         default:
00233             return radius_put_vendor_attr($this->res, $vendor, $attrib, $value);
00234         }
00235 
00236     }
00237 
00243     function dumpAttributes()
00244     {
00245         foreach ($this->attributes as $name => $data) {
00246             echo "$name:$data<br>\n";
00247         }
00248     }
00249 
00255     function open()
00256     {
00257     }
00258 
00264     function createRequest()
00265     {
00266     }
00267 
00273     function putStandardAttributes()
00274     {
00275         if (!$this->useStandardAttributes)
00276                 return;
00277 
00278         if (isset($_SERVER)) {
00279             $var = &$_SERVER;
00280         } else {
00281             $var = &$GLOBALS['HTTP_SERVER_VARS'];
00282         }
00283 
00284         $this->putAttribute(RADIUS_NAS_IDENTIFIER, isset($var['HTTP_HOST']) ? $var['HTTP_HOST'] : 'localhost');
00285         $this->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_VIRTUAL);
00286         $this->putAttribute(RADIUS_SERVICE_TYPE, RADIUS_FRAMED);
00287         $this->putAttribute(RADIUS_FRAMED_PROTOCOL, RADIUS_PPP);
00288         $this->putAttribute(RADIUS_CALLING_STATION_ID, isset($var['REMOTE_HOST']) ? $var['REMOTE_HOST'] : '127.0.0.1');
00289     }
00290 
00296     function putAuthAttributes()
00297     {
00298         if (isset($this->username)) {
00299             $this->putAttribute(RADIUS_USER_NAME, $this->username);
00300         }
00301     }
00302 
00315     function putServer($servername, $port = 0, $sharedsecret = 'testing123', $timeout = 3, $maxtries = 3)
00316     {
00317         if (!radius_add_server($this->res, $servername, $port, $sharedsecret, $timeout, $maxtries)) {
00318             return false;
00319         }
00320         return true;
00321     }
00322 
00330     function putConfigfile($file)
00331     {
00332         if (!radius_config($this->res, $file)) {
00333             return false;
00334         }
00335         return true;
00336     }
00337 
00344     function start()
00345     {
00346         if (!$this->open()) {
00347             return false;
00348         }
00349 
00350         foreach ($this->_servers as $s) {
00351                 // Servername, port, sharedsecret, timeout, retries
00352             if (!$this->putServer($s[0], $s[1], $s[2], $s[3], $s[4])) {
00353                 return false;
00354             }
00355         }
00356 
00357         if (!empty($this->_configfile)) {
00358             if (!$this->putConfigfile($this->_configfile)) {
00359                 return false;
00360             }
00361         }
00362 
00363         $this->createRequest();
00364         $this->putStandardAttributes();
00365         $this->putAuthAttributes();
00366         return true;
00367     }
00368 
00375     function send()
00376     {
00377         $req = radius_send_request($this->res);
00378         if (!$req) {
00379             return $this->raiseError('Error sending request: ' . $this->getError());
00380         }
00381 
00382         switch($req) {
00383         case RADIUS_ACCESS_ACCEPT:
00384             if (is_subclass_of($this, 'auth_radius_acct')) {
00385                 return $this->raiseError('RADIUS_ACCESS_ACCEPT is unexpected for accounting');
00386             }
00387             return true;
00388 
00389         case RADIUS_ACCESS_REJECT:
00390             return false;
00391 
00392         case RADIUS_ACCOUNTING_RESPONSE:
00393             if (is_subclass_of($this, 'auth_radius_pap')) {
00394                 return $this->raiseError('RADIUS_ACCOUNTING_RESPONSE is unexpected for authentication');
00395             }
00396             return true;
00397 
00398         default:
00399             return $this->raiseError("Unexpected return value: $req");
00400         }
00401 
00402     }
00403 
00416     function getAttributes()
00417     {
00418 
00419         while ($attrib = radius_get_attr($this->res)) {
00420 
00421             if (!is_array($attrib)) {
00422                 return false;
00423             }
00424 
00425             $attr = $attrib['attr'];
00426             $data = $attrib['data'];
00427 
00428             $this->rawAttributes[$attr] = $data;
00429 
00430             switch ($attr) {
00431             case RADIUS_FRAMED_IP_ADDRESS:
00432                 $this->attributes['framed_ip'] = radius_cvt_addr($data);
00433                 break;
00434 
00435             case RADIUS_FRAMED_IP_NETMASK:
00436                 $this->attributes['framed_mask'] = radius_cvt_addr($data);
00437                 break;
00438 
00439             case RADIUS_FRAMED_MTU:
00440                 $this->attributes['framed_mtu'] = radius_cvt_int($data);
00441                 break;
00442 
00443             case RADIUS_FRAMED_COMPRESSION:
00444                 $this->attributes['framed_compression'] = radius_cvt_int($data);
00445                 break;
00446 
00447             case RADIUS_SESSION_TIMEOUT:
00448                 $this->attributes['session_timeout'] = radius_cvt_int($data);
00449                 break;
00450 
00451             case RADIUS_IDLE_TIMEOUT:
00452                 $this->attributes['idle_timeout'] = radius_cvt_int($data);
00453                 break;
00454 
00455             case RADIUS_SERVICE_TYPE:
00456                 $this->attributes['service_type'] = radius_cvt_int($data);
00457                 break;
00458 
00459             case RADIUS_CLASS:
00460                 $this->attributes['class'] = radius_cvt_string($data);
00461                 break;
00462 
00463             case RADIUS_FRAMED_PROTOCOL:
00464                 $this->attributes['framed_protocol'] = radius_cvt_int($data);
00465                 break;
00466 
00467             case RADIUS_FRAMED_ROUTING:
00468                 $this->attributes['framed_routing'] = radius_cvt_int($data);
00469                 break;
00470 
00471             case RADIUS_FILTER_ID:
00472                 $this->attributes['filter_id'] = radius_cvt_string($data);
00473                 break;
00474 
00475             case RADIUS_REPLY_MESSAGE:
00476                 $this->attributes['reply_message'] = radius_cvt_string($data);
00477                 break;
00478 
00479             case RADIUS_VENDOR_SPECIFIC:
00480                 $attribv = radius_get_vendor_attr($data);
00481                 if (!is_array($attribv)) {
00482                     return false;
00483                 }
00484 
00485                 $vendor = $attribv['vendor'];
00486                 $attrv = $attribv['attr'];
00487                 $datav = $attribv['data'];
00488 
00489                 $this->rawVendorAttributes[$vendor][$attrv] = $datav;
00490 
00491                 if ($vendor == RADIUS_VENDOR_MICROSOFT) {
00492 
00493                     switch ($attrv) {
00494                     case RADIUS_MICROSOFT_MS_CHAP2_SUCCESS:
00495                         $this->attributes['ms_chap2_success'] = radius_cvt_string($datav);
00496                         break;
00497 
00498                     case RADIUS_MICROSOFT_MS_CHAP_ERROR:
00499                         $this->attributes['ms_chap_error'] = radius_cvt_string(substr($datav,1));
00500                         break;
00501 
00502                     case RADIUS_MICROSOFT_MS_CHAP_DOMAIN:
00503                         $this->attributes['ms_chap_domain'] = radius_cvt_string($datav);
00504                         break;
00505 
00506                     case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
00507                         $this->attributes['ms_mppe_encryption_policy'] = radius_cvt_int($datav);
00508                         break;
00509 
00510                     case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
00511                         $this->attributes['ms_mppe_encryption_types'] = radius_cvt_int($datav);
00512                         break;
00513 
00514                     case RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS:
00515                         $demangled = radius_demangle($this->res, $datav);
00516                         $this->attributes['ms_chap_mppe_lm_key'] = substr($demangled, 0, 8);
00517                         $this->attributes['ms_chap_mppe_nt_key'] = substr($demangled, 8, RADIUS_MPPE_KEY_LEN);
00518                         break;
00519 
00520                     case RADIUS_MICROSOFT_MS_MPPE_SEND_KEY:
00521                         $this->attributes['ms_chap_mppe_send_key'] = radius_demangle_mppe_key($this->res, $datav);
00522                         break;
00523 
00524                     case RADIUS_MICROSOFT_MS_MPPE_RECV_KEY:
00525                         $this->attributes['ms_chap_mppe_recv_key'] = radius_demangle_mppe_key($this->res, $datav);
00526                         break;
00527 
00528                     case RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER:
00529                         $this->attributes['ms_primary_dns_server'] = radius_cvt_string($datav);
00530                         break;
00531                     }
00532                 }
00533                 break;
00534 
00535             }
00536         }
00537 
00538         return true;
00539     }
00540 
00549     function close()
00550     {
00551         if ($this->res != null) {
00552             radius_close($this->res);
00553             $this->res = null;
00554         }
00555         $this->username = str_repeat("\0", strlen($this->username));
00556         $this->password = str_repeat("\0", strlen($this->password));
00557     }
00558 
00559 }
00560 
00568 class Auth_RADIUS_PAP extends Auth_RADIUS
00569 {
00570 
00578     function Auth_RADIUS_PAP($username = null, $password = null)
00579     {
00580         $this->Auth_RADIUS();
00581         $this->username = $username;
00582         $this->password = $password;
00583     }
00584 
00593     function open()
00594     {
00595         $this->res = radius_auth_open();
00596         if (!$this->res) {
00597             return false;
00598         }
00599         return true;
00600     }
00601 
00610     function createRequest()
00611     {
00612         if (!radius_create_request($this->res, RADIUS_ACCESS_REQUEST)) {
00613             return false;
00614         }
00615         return true;
00616     }
00617 
00623     function putAuthAttributes()
00624     {
00625         if (isset($this->username)) {
00626             $this->putAttribute(RADIUS_USER_NAME, $this->username);
00627         }
00628         if (isset($this->password)) {
00629             $this->putAttribute(RADIUS_USER_PASSWORD, $this->password);
00630         }
00631     }
00632 
00633 }
00634 
00644 class Auth_RADIUS_CHAP_MD5 extends Auth_RADIUS_PAP
00645 {
00650     var $challenge = null;
00651 
00656     var $response = null;
00657 
00662     var $chapid = 1;
00663 
00672     function Auth_RADIUS_CHAP_MD5($username = null, $challenge = null, $chapid = 1)
00673     {
00674         $this->Auth_RADIUS_PAP();
00675         $this->username = $username;
00676         $this->challenge = $challenge;
00677         $this->chapid = $chapid;
00678     }
00679 
00688     function putAuthAttributes()
00689     {
00690         if (isset($this->username)) {
00691             $this->putAttribute(RADIUS_USER_NAME, $this->username);
00692         }
00693         if (isset($this->response)) {
00694             $response = pack('C', $this->chapid) . $this->response;
00695             $this->putAttribute(RADIUS_CHAP_PASSWORD, $response);
00696         }
00697         if (isset($this->challenge)) {
00698             $this->putAttribute(RADIUS_CHAP_CHALLENGE, $this->challenge);
00699         }
00700     }
00701 
00710     function close()
00711     {
00712         Auth_RADIUS_PAP::close();
00713         $this->challenge =  str_repeat("\0", strlen($this->challenge));
00714         $this->response =  str_repeat("\0", strlen($this->response));
00715     }
00716 
00717 }
00718 
00726 class Auth_RADIUS_MSCHAPv1 extends Auth_RADIUS_CHAP_MD5
00727 {
00732     var $lmResponse = null;
00733 
00739     var $flags = 1;
00740 
00755     function putAuthAttributes()
00756     {
00757         if (isset($this->username)) {
00758             $this->putAttribute(RADIUS_USER_NAME, $this->username);
00759         }
00760         if (isset($this->response) || isset($this->lmResponse)) {
00761             $lmResp = isset($this->lmResponse) ? $this->lmResponse : str_repeat ("\0", 24);
00762             $ntResp = isset($this->response)   ? $this->response :   str_repeat ("\0", 24);
00763             $resp = pack('CC', $this->chapid, $this->flags) . $lmResp . $ntResp;
00764             $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_RESPONSE, $resp);
00765         }
00766         if (isset($this->challenge)) {
00767             $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
00768         }
00769     }
00770 }
00771 
00779 class Auth_RADIUS_MSCHAPv2 extends Auth_RADIUS_MSCHAPv1
00780 {
00785     var $challenge = null;
00786 
00791     var $peerChallenge = null;
00792 
00808     function putAuthAttributes()
00809     {
00810         if (isset($this->username)) {
00811             $this->putAttribute(RADIUS_USER_NAME, $this->username);
00812         }
00813         if (isset($this->response) && isset($this->peerChallenge)) {
00814             // Response: chapid, flags (1 = use NT Response), Peer challenge, reserved, Response
00815             $resp = pack('CCa16a8a24',$this->chapid , 1, $this->peerChallenge, str_repeat("\0", 8), $this->response);
00816             $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP2_RESPONSE, $resp);
00817         }
00818         if (isset($this->challenge)) {
00819             $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
00820         }
00821     }
00822 
00831     function close()
00832     {
00833         Auth_RADIUS_MSCHAPv1::close();
00834         $this->peerChallenge = str_repeat("\0", strlen($this->peerChallenge));
00835     }
00836 }
00837 
00845 class Auth_RADIUS_Acct extends Auth_RADIUS
00846 {
00852     var $authentic = null;
00853 
00859     var $status_type = null;
00860 
00865     var $session_time = null;
00866 
00871     var $session_id = null;
00872 
00879     function Auth_RADIUS_Acct()
00880     {
00881         $this->Auth_RADIUS();
00882 
00883         if (isset($_SERVER)) {
00884             $var = &$_SERVER;
00885         } else {
00886             $var = &$GLOBALS['HTTP_SERVER_VARS'];
00887         }
00888 
00889         $this->session_id = sprintf("%s:%d-%s", isset($var['REMOTE_ADDR']) ? $var['REMOTE_ADDR'] : '127.0.0.1' , getmypid(), get_current_user());
00890     }
00891 
00900     function open()
00901     {
00902         $this->res = radius_acct_open();
00903         if (!$this->res) {
00904             return false;
00905         }
00906         return true;
00907     }
00908 
00917     function createRequest()
00918     {
00919         if (!radius_create_request($this->res, RADIUS_ACCOUNTING_REQUEST)) {
00920             return false;
00921         }
00922         return true;
00923     }
00924 
00932     function putAuthAttributes()
00933     {
00934         $this->putAttribute(RADIUS_ACCT_SESSION_ID, $this->session_id);
00935         $this->putAttribute(RADIUS_ACCT_STATUS_TYPE, $this->status_type);
00936         if (isset($this->session_time) && $this->status_type == RADIUS_STOP) {
00937             $this->putAttribute(RADIUS_ACCT_SESSION_TIME, $this->session_time);
00938         }
00939         if (isset($this->authentic)) {
00940             $this->putAttribute(RADIUS_ACCT_AUTHENTIC, $this->authentic);
00941         }
00942 
00943     }
00944 
00945 }
00946 
00954 class Auth_RADIUS_Acct_Start extends Auth_RADIUS_Acct
00955 {
00961     var $status_type = RADIUS_START;
00962 }
00963 
00971 class Auth_RADIUS_Acct_Stop extends Auth_RADIUS_Acct
00972 {
00978     var $status_type = RADIUS_STOP;
00979 }
00980 
00981 if (!defined('RADIUS_UPDATE'))
00982     define('RADIUS_UPDATE', 3);
00983 
00991 class Auth_RADIUS_Acct_Update extends Auth_RADIUS_Acct
00992 {
00998     var $status_type = RADIUS_UPDATE;
00999 }
01000 
01001 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations