source-class-Radius

It appears that you are using AdBlocking software. The cost of running this website is covered by advertisements. If you like it please feel free to a small amount of money to secure the future of this website.
Overview

Classes

Interfaces

Exceptions

Functions

  1: <?php
  2: /*********************************************************************
  3:  *
  4:  * Pure PHP radius class
  5:  *
  6:  * This Radius class is a radius client implementation in pure PHP
  7:  * following the RFC 2865 rules (http://www.ietf.org/rfc/rfc2865.txt)
  8:  *
  9:  * This class works with at least the following RADIUS servers:
 10:  *  - Authenex Strong Authentication System (ASAS) with two-factor authentication
 11:  *  - FreeRADIUS, a free Radius server implementation for Linux and *nix environments
 12:  *  - Microsoft Radius server IAS
 13:  *  - Mideye RADIUS server (http://www.mideye.com)
 14:  *  - Radl, a free Radius server for Windows
 15:  *  - RSA SecurID
 16:  *  - VASCO Middleware 3.0 server
 17:  *  - WinRadius, Windows Radius server (free for 5 users)
 18:  *  - ZyXEL ZyWALL OTP (Authenex ASAS branded by ZyXEL, cheaper)
 19:  *
 20:  *
 21:  * LICENCE
 22:  *
 23:  *   Copyright (c) 2008, SysCo systemes de communication sa
 24:  *   SysCo (tm) is a trademark of SysCo systemes de communication sa
 25:  *   (http://www.sysco.ch/)
 26:  *   All rights reserved.
 27:  *
 28:  *   This file is part of the Pure PHP radius class
 29:  *
 30:  *   Pure PHP radius class is free software; you can redistribute it and/or
 31:  *   modify it under the terms of the GNU Lesser General Public License as
 32:  *   published by the Free Software Foundation, either version 3 of the License,
 33:  *   or (at your option) any later version.
 34:  *
 35:  *   Pure PHP radius class is distributed in the hope that it will be useful,
 36:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 37:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 38:  *   GNU Lesser General Public License for more details.
 39:  *
 40:  *   You should have received a copy of the GNU Lesser General Public
 41:  *   License along with Pure PHP radius class.
 42:  *   If not, see <http://www.gnu.org/licenses/>.
 43:  *
 44:  *
 45:  * @author: SysCo/al
 46:  * @since CreationDate: 2008-01-04
 47:  * @copyright (c) 2008 by SysCo systemes de communication sa
 48:  * @version $LastChangedRevision: 1.2.2 $
 49:  * @version $LastChangedDate: 2009-01-05 $
 50:  * @version $LastChangedBy: SysCo/al $
 51:  * @link $HeadURL: radius.class.php $
 52:  * @link http://developer.sysco.ch/php/
 53:  * @link developer@sysco.ch
 54:  * Language: PHP 4.0.7 or higher
 55:  *
 56:  *
 57:  * Usage
 58:  *
 59:  *   require_once('radius.class.php');
 60:  *   $radius = new Radius($ip_radius_server = 'radius_server_ip_address', $shared_secret = 'radius_shared_secret'[, $radius_suffix = 'optional_radius_suffix'[, $udp_timeout = udp_timeout_in_seconds[, $authentication_port = 1812]]]);
 61:  *   $result = $radius->Access_Request($username = 'username', $password = 'password'[, $udp_timeout = udp_timeout_in_seconds]);
 62:  *
 63:  *
 64:  * Examples
 65:  *
 66:  *   Example 1
 67:  *     <?php
 68:  *         require_once('radius.class.php');
 69:  *         $radius = new Radius('127.0.0.1', 'secret');
 70:  *         $radius->SetNasIpAddress('1.2.3.4'); // Needed for some devices, and not auto_detected if PHP not runned through a web server
 71:  *         if ($radius->AccessRequest('user', 'pass'))
 72:  *         {
 73:  *             echo "Authentication accepted.";
 74:  *         }
 75:  *         else
 76:  *         {
 77:  *             echo "Authentication rejected.";
 78:  *         }
 79:  *     ?>
 80:  *
 81:  *   Example 2
 82:  *     <?php
 83:  *         require_once('radius.class.php');
 84:  *         $radius = new Radius('127.0.0.1', 'secret');
 85:  *         $radius->SetNasPort(0);
 86:  *         $radius->SetNasIpAddress('1.2.3.4'); // Needed for some devices, and not auto_detected if PHP not runned through a web server
 87:  *         if ($radius->AccessRequest('user', 'pass'))
 88:  *         {
 89:  *             echo "Authentication accepted.";
 90:  *             echo "<br />";
 91:  *         }
 92:  *         else
 93:  *         {
 94:  *             echo "Authentication rejected.";
 95:  *             echo "<br />";
 96:  *         }
 97:  *         echo $radius->GetReadableReceivedAttributes();
 98:  *     ?>
 99:  *
100:  *
101:  * External file needed
102:  *
103:  *   none.
104:  *
105:  *
106:  * External file created
107:  *
108:  *   none.
109:  *
110:  *
111:  * Special issues
112:  *
113:  *   - Sockets support must be enabled.
114:  *     * In Linux and *nix environments, the extension is enabled at
115:  *       compile time using the --enable-sockets configure option
116:  *     * In Windows, PHP Sockets can be activated by un-commenting
117:  *       extension=php_sockets.dll in php.ini
118:  *
119:  *
120:  * Other related ressources
121:  *
122:  *   FreeRADIUS, a free Radius server implementation for Linux and *nix environments:
123:  *     http://www.freeradius.org/
124:  *
125:  *   WinRadius, Windows Radius server (free for 5 users):
126:  *     http://www.itconsult2000.com/en/product/WinRadius.zip
127:  *
128:  *   Radl, a free Radius server for Windows:
129:  *     http://www.loriotpro.com/Products/RadiusServer/FreeRadiusServer_EN.php
130:  *
131:  *   DOS command line Radius client:
132:  *     http://www.itconsult2000.com/en/product/WinRadiusClient.zip
133:  *
134:  *
135:  * Users feedbacks and comments
136:  *
137:  * 2008-07-02 Pim Koeman/Parantion
138:  *
139:  *   When using a radius connection behind a linux iptables firewall
140:  *   allow port 1812 and 1813 with udp protocol
141:  *
142:  *   IPTABLES EXAMPLE (command line):
143:  *   iptables -A AlwaysACCEPT -p udp --dport 1812 -j ACCEPT
144:  *   iptables -A AlwaysACCEPT -p udp --dport 1813 -j ACCEPT
145:  *
146:  *   or put the lines in /etc/sysconfig/iptables (red-hat type systems (fedora, centos, rhel etc.)
147:  *   -A AlwaysACCEPT -p udp --dport 1812 -j ACCEPT
148:  *   -A AlwaysACCEPT -p udp --dport 1813 -j ACCEPT
149:  *
150:  *
151:  * Change Log
152:  *
153:  *   2009-01-05 1.2.2 SysCo/al Added Robert Svensson feedback, Mideye RADIUS server is supported
154:  *   2008-11-11 1.2.1 SysCo/al Added Carlo Ferrari resolution in examples (add NAS IP Address for a VASCO Middleware server)
155:  *   2008-07-07 1.2   SysCo/al Added Pim Koeman (Parantion) contribution
156:  *                              - comments concerning using radius behind a linux iptables firewall
157:  *                             Added Jon Bright (tick Trading Software AG) contribution
158:  *                              - false octal encoding with 0xx indexes (indexes are now rewritten in xx only)
159:  *                              - challenge/response support for the RSA SecurID New-PIN mode
160:  *                             Added GetRadiusPacketInfo() method
161:  *                             Added GetAttributesInfo() method
162:  *                             Added DecodeVendorSpecificContent() (to answer Raul Carvalho's question)
163:  *                             Added Decoded Vendor Specific Content in debug messages
164:  *   2008-02-04 1.1   SysCo/al Typo error for the udp_timeout parameter (line 256 in the version 1.0)
165:  *   2008-01-07 1.0   SysCo/al Initial release
166:  *
167:  *********************************************************************/
168: 
169: // 2010-08-09 Nicola Asuni : Code clean-up and PHP conversion
170: 
171: /*********************************************************************
172:  *
173:  * Radius
174:  * Pure PHP radius class
175:  *
176:  * Creation 2008-01-04
177:  * Update 2009-01-05
178:  * @package radius
179:  * @version v.1.2.2
180:  * @author SysCo/al
181:  *
182:  *********************************************************************/
183: class Radius {
184:     /**
185:     * @var Radius server IP address
186:     */
187:     public $_ip_radius_server;
188: 
189:     /**
190:     * @var Shared secret with the radius server
191:     */
192:     public $_shared_secret;
193: 
194:     /**
195:     * @var Radius suffix (default is '');
196:     */
197:     public $_radius_suffix;
198: 
199:     /**
200:     * @var Timeout of the UDP connection in seconds (default value is 5)
201:     */
202:     public $_udp_timeout;
203: 
204:     /**
205:     * @var Authentication port (default value is 1812)
206:     */
207:     public $_authentication_port;
208: 
209:     /**
210:     * @var Accouting port (default value is 1813)
211:     */
212:     public $_accounting_port;
213: 
214:     /**
215:     * @var NAS IP address
216:     */
217:     public $_nas_ip_address;
218: 
219:     /**
220:     * @var NAS port
221:     */
222:     public $_nas_port;
223: 
224:     /**
225:     * @var Encrypted password, as described in the RFC 2865
226:     */
227:     public $_encrypted_password;
228: 
229:     /**
230:     * @var Remote IP address of the user
231:     */
232:     public $_user_ip_address;
233: 
234:     /**
235:     * @var Request-Authenticator, 16 octets random number
236:     */
237:     public $_request_authenticator;
238: 
239:     /**
240:     * @var Request-Authenticator, 16 octets random number
241:     */
242:     public $_response_authenticator;
243: 
244:     /**
245:     * @var Username to sent to the Radius server
246:     */
247:     public $_username;
248: 
249:     /**
250:     * @var Password to sent to the Radius server (clear password, must be encrypted)
251:     */
252:     public $_password;
253: 
254:     /**
255:     * @var Identifier field for the packet to be sent
256:     */
257:     public $_identifier_to_send;
258: 
259:     /**
260:     * @var Identifier field for the received packet
261:     */
262:     public $_identifier_received;
263: 
264:     /**
265:     * @var Radius packet code (1=Access-Request, 2=Access-Accept, 3=Access-Reject, 4=Accounting-Request, 5=Accounting-Response, 11=Access-Challenge, 12=Status-Server (experimental), 13=Status-Client (experimental), 255=Reserved
266:     */
267:     public $_radius_packet_to_send;
268: 
269:     /**
270:     * @var Radius packet code (1=Access-Request, 2=Access-Accept, 3=Access-Reject, 4=Accounting-Request, 5=Accounting-Response, 11=Access-Challenge, 12=Status-Server (experimental), 13=Status-Client (experimental), 255=Reserved
271:     */
272:     public $_radius_packet_received;
273: 
274:     /**
275:     * @var Radius attributes to send
276:     */
277:     public $_attributes_to_send;
278: 
279:     /**
280:     * @var Radius attributes received
281:     */
282:     public $_attributes_received;
283: 
284:     /**
285:     * @var Socket connection
286:     */
287:     public $_socket_to_server;
288: 
289:     /**
290:     * @var Debug mode flag
291:     */
292:     public $_debug_mode;
293: 
294:     /**
295:     * @var Attributes info array
296:     */
297:     public $_attributes_info;
298: 
299:     /**
300:     * @var Radius packet codes info array
301:     */
302:     public $_radius_packet_info;
303: 
304:     /**
305:     * @var Last error code
306:     */
307:     public $_last_error_code;
308: 
309:     /**
310:     * @var Last error message
311:     */
312:     public $_last_error_message;
313: 
314: 
315:     /*********************************************************************
316:     *
317:     * Name: Radius
318:     * short description: Radius class constructor
319:     *
320:     * Creation 2008-01-04
321:     * Update 2009-01-05
322:     * @version v.1.2.2
323:     * @author SysCo/al
324:     * @param string ip address of the radius server
325:     * @param string shared secret with the radius server
326:     * @param string radius domain name suffix (default is empty)
327:     * @param integer UDP timeout (default is 5)
328:     * @param integer authentication port
329:     * @param integer accounting port
330:     * @return NULL
331:     *********************************************************************/
332:     public function __construct($ip_radius_server = '127.0.0.1', $shared_secret = '', $radius_suffix = '', $udp_timeout = 5, $authentication_port = 1812, $accounting_port = 1813) {
333:         $this->_radius_packet_info[1] = 'Access-Request';
334:         $this->_radius_packet_info[2] = 'Access-Accept';
335:         $this->_radius_packet_info[3] = 'Access-Reject';
336:         $this->_radius_packet_info[4] = 'Accounting-Request';
337:         $this->_radius_packet_info[5] = 'Accounting-Response';
338:         $this->_radius_packet_info[11] = 'Access-Challenge';
339:         $this->_radius_packet_info[12] = 'Status-Server (experimental)';
340:         $this->_radius_packet_info[13] = 'Status-Client (experimental)';
341:         $this->_radius_packet_info[255] = 'Reserved';
342:         $this->_attributes_info[1] = array('User-Name', 'S');
343:         $this->_attributes_info[2] = array('User-Password', 'S');
344:         $this->_attributes_info[3] = array('CHAP-Password', 'S'); // Type (1) / Length (1) / CHAP Ident (1) / String
345:         $this->_attributes_info[4] = array('NAS-IP-Address', 'A');
346:         $this->_attributes_info[5] = array('NAS-Port', 'I');
347:         $this->_attributes_info[6] = array('Service-Type', 'I');
348:         $this->_attributes_info[7] = array('Framed-Protocol', 'I');
349:         $this->_attributes_info[8] = array('Framed-IP-Address', 'A');
350:         $this->_attributes_info[9] = array('Framed-IP-Netmask', 'A');
351:         $this->_attributes_info[10] = array('Framed-Routing', 'I');
352:         $this->_attributes_info[11] = array('Filter-Id', 'T');
353:         $this->_attributes_info[12] = array('Framed-MTU', 'I');
354:         $this->_attributes_info[13] = array('Framed-Compression', 'I');
355:         $this->_attributes_info[14] = array( 'Login-IP-Host', 'A');
356:         $this->_attributes_info[15] = array('Login-service', 'I');
357:         $this->_attributes_info[16] = array('Login-TCP-Port', 'I');
358:         $this->_attributes_info[17] = array('(unassigned)', '');
359:         $this->_attributes_info[18] = array('Reply-Message', 'T');
360:         $this->_attributes_info[19] = array('Callback-Number', 'S');
361:         $this->_attributes_info[20] = array('Callback-Id', 'S');
362:         $this->_attributes_info[21] = array('(unassigned)', '');
363:         $this->_attributes_info[22] = array('Framed-Route', 'T');
364:         $this->_attributes_info[23] = array('Framed-IPX-Network', 'I');
365:         $this->_attributes_info[24] = array('State', 'S');
366:         $this->_attributes_info[25] = array('Class', 'S');
367:         $this->_attributes_info[26] = array('Vendor-Specific', 'S'); // Type (1) / Length (1) / Vendor-Id (4) / Vendor type (1) / Vendor length (1) / Attribute-Specific...
368:         $this->_attributes_info[27] = array('Session-Timeout', 'I');
369:         $this->_attributes_info[28] = array('Idle-Timeout', 'I');
370:         $this->_attributes_info[29] = array('Termination-Action', 'I');
371:         $this->_attributes_info[30] = array('Called-Station-Id', 'S');
372:         $this->_attributes_info[31] = array('Calling-Station-Id', 'S');
373:         $this->_attributes_info[32] = array('NAS-Identifier', 'S');
374:         $this->_attributes_info[33] = array('Proxy-State', 'S');
375:         $this->_attributes_info[34] = array('Login-LAT-Service', 'S');
376:         $this->_attributes_info[35] = array('Login-LAT-Node', 'S');
377:         $this->_attributes_info[36] = array('Login-LAT-Group', 'S');
378:         $this->_attributes_info[37] = array('Framed-AppleTalk-Link', 'I');
379:         $this->_attributes_info[38] = array('Framed-AppleTalk-Network', 'I');
380:         $this->_attributes_info[39] = array('Framed-AppleTalk-Zone', 'S');
381:         $this->_attributes_info[60] = array('CHAP-Challenge', 'S');
382:         $this->_attributes_info[61] = array('NAS-Port-Type', 'I');
383:         $this->_attributes_info[62] = array('Port-Limit', 'I');
384:         $this->_attributes_info[63] = array('Login-LAT-Port', 'S');
385:         $this->_attributes_info[76] = array('Prompt', 'I');
386:         $this->_identifier_to_send = 0;
387:         $this->_user_ip_address = (isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'0.0.0.0');
388:         $this->GenerateRequestAuthenticator();
389:         $this->SetIpRadiusServer($ip_radius_server);
390:         $this->SetSharedSecret($shared_secret);
391:         $this->SetAuthenticationPort($authentication_port);
392:         $this->SetAccountingPort($accounting_port);
393:         $this->SetRadiusSuffix($radius_suffix);
394:         $this->SetUdpTimeout($udp_timeout);
395:         $this->SetUsername();
396:         $this->SetPassword();
397:         $this->SetNasIpAddress();
398:         $this->SetNasPort();
399:         $this->ClearLastError();
400:         $this->ClearDataToSend();
401:         $this->ClearDataReceived();
402:     }
403: 
404:     public function GetNextIdentifier() {
405:         $this->_identifier_to_send = (($this->_identifier_to_send + 1) % 256);
406:         return $this->_identifier_to_send;
407:     }
408: 
409:     public function GenerateRequestAuthenticator() {
410:         $this->_request_authenticator = '';
411:         for ($ra_loop = 0; $ra_loop <= 15; ++$ra_loop) {
412:             $this->_request_authenticator .= chr(rand(1, 255));
413:         }
414:     }
415: 
416:     public function GetRequestAuthenticator() {
417:         return $this->_request_authenticator;
418:     }
419: 
420:     public function GetLastError() {
421:         if (0 < $this->_last_error_code) {
422:             return $this->_last_error_message.' ('.$this->_last_error_code.')';
423:         } else {
424:             return '';
425:         }
426:     }
427: 
428:     public function ClearDataToSend() {
429:         $this->_radius_packet_to_send = 0;
430:         $this->_attributes_to_send = NULL;
431:     }
432: 
433:     public function ClearDataReceived() {
434:         $this->_radius_packet_received = 0;
435:         $this->_attributes_received = NULL;
436:     }
437: 
438:     public function SetPacketCodeToSend($packet_code) {
439:         $this->_radius_packet_to_send = $packet_code;
440:     }
441: 
442:     public function SetDebugMode($debug_mode) {
443:         $this->_debug_mode = (TRUE === $debug_mode);
444:     }
445: 
446:     public function SetIpRadiusServer($ip_radius_server) {
447:         $this->_ip_radius_server = gethostbyname($ip_radius_server);
448:     }
449: 
450:     public function SetSharedSecret($shared_secret) {
451:         $this->_shared_secret = $shared_secret;
452:     }
453: 
454:     public function SetRadiusSuffix($radius_suffix) {
455:         $this->_radius_suffix = $radius_suffix;
456:     }
457: 
458:     public function SetUsername($username = '') {
459:         $temp_username = $username;
460:         if (false === strpos($temp_username, '@')) {
461:             $temp_username .= $this->_radius_suffix;
462:         }
463:         $this->_username = $temp_username;
464:         $this->SetAttribute(1, $this->_username);
465:     }
466: 
467:     public function SetPassword($password = '') {
468:         $this->_password = $password;
469:         $encrypted_password = '';
470:         $padded_password = $password;
471:         if (0 != (strlen($password)%16)) {
472:             $padded_password .= str_repeat(chr(0),(16-strlen($password)%16));
473:         }
474:         $previous_result = $this->_request_authenticator;
475:         for ($full_loop = 0; $full_loop < (strlen($padded_password)/16); $full_loop++) {
476:             $xor_value = md5($this->_shared_secret.$previous_result);
477:             $previous_result = '';
478:             for ($xor_loop = 0; $xor_loop <= 15; $xor_loop++) {
479:                 $value1 = ord(substr($padded_password, ($full_loop * 16) + $xor_loop, 1));
480:                 $value2 = hexdec(substr($xor_value, 2*$xor_loop, 2));
481:                 $xor_result = $value1 ^ $value2;
482:                 $previous_result .= chr($xor_result);
483:             }
484:             $encrypted_password .= $previous_result;
485:         }
486:         $this->_encrypted_password = $encrypted_password;
487:         $this->SetAttribute(2, $this->_encrypted_password);
488:     }
489: 
490:     public function SetNasIPAddress($nas_ip_address = '') {
491:         if (0 < strlen($nas_ip_address)) {
492:             $this->_nas_ip_address = gethostbyname($nas_ip_address);
493:         } else {
494:             $this->_nas_ip_address = gethostbyname(isset($_SERVER['SERVER_ADDR'])?$_SERVER['SERVER_ADDR']:'0.0.0.0');
495:         }
496:         $this->SetAttribute(4, $this->_nas_ip_address);
497:     }
498: 
499:     public function SetNasPort($nas_port = 0) {
500:         $this->_nas_port = intval($nas_port);
501:         $this->SetAttribute(5, $this->_nas_port);
502:     }
503: 
504:     public function SetUdpTimeout($udp_timeout = 5) {
505:         if (intval($udp_timeout) > 0) {
506:             $this->_udp_timeout = intval($udp_timeout);
507:         }
508:     }
509: 
510:     public function ClearLastError() {
511:         $this->_last_error_code = 0;
512:         $this->_last_error_message = '';
513:     }
514: 
515:     public function SetAuthenticationPort($authentication_port) {
516:         if ((intval($authentication_port) > 0) && (intval($authentication_port) < 65536)) {
517:             $this->_authentication_port = intval($authentication_port);
518:         }
519:     }
520: 
521:     public function SetAccountingPort($accounting_port) {
522:         if ((intval($accounting_port) > 0) && (intval($accounting_port) < 65536)) {
523:             $this->_accounting_port = intval($accounting_port);
524:         }
525:     }
526: 
527:     public function GetReceivedPacket() {
528:         return $this->_radius_packet_received;
529:     }
530: 
531:     public function GetReceivedAttributes() {
532:         return $this->_attributes_received;
533:     }
534: 
535:     public function GetReadableReceivedAttributes() {
536:         $readable_attributes = '';
537:         if (isset($this->_attributes_received)) {
538:             foreach($this->_attributes_received as $one_received_attribute) {
539:                 $attributes_info = $this->GetAttributesInfo($one_received_attribute[0]);
540:                 $readable_attributes .= $attributes_info[0].': ';
541:                 if (26 == $one_received_attribute[0]) {
542:                     $vendor_array = $this->DecodeVendorSpecificContent($one_received_attribute[1]);
543:                     foreach($vendor_array as $vendor_one) {
544:                         $readable_attributes .= 'Vendor-Id: '.$vendor_one[0].', Vendor-type: '.$vendor_one[1].', Attribute-specific: '.$vendor_one[2];
545:                     }
546:                 } else {
547:                     $readable_attributes .= $one_received_attribute[1];
548:                 }
549:                 $readable_attributes .= "<br />\n";
550:             }
551:         }
552:         return $readable_attributes;
553:     }
554: 
555:     public function GetAttribute($attribute_type) {
556:         $attribute_value = NULL;
557:         foreach($this->_attributes_received as $one_received_attribute) {
558:             if (intval($attribute_type) == $one_received_attribute[0]) {
559:                 $attribute_value = $one_received_attribute[1];
560:                 break;
561:             }
562:         }
563:         return $attribute_value;
564:     }
565: 
566:     public function GetRadiusPacketInfo($info_index) {
567:         if (isset($this->_radius_packet_info[intval($info_index)])) {
568:             return $this->_radius_packet_info[intval($info_index)];
569:         } else {
570:             return '';
571:         }
572:     }
573: 
574:     public function GetAttributesInfo($info_index) {
575:         if (isset($this->_attributes_info[intval($info_index)])) {
576:             return $this->_attributes_info[intval($info_index)];
577:         } else {
578:             return array('','');
579:         }
580:     }
581: 
582:     public function DebugInfo($debug_info) {
583:         if ($this->_debug_mode) {
584:             echo date('Y-m-d H:i:s').' DEBUG: ';
585:             echo $debug_info;
586:             echo '<br />';
587:             flush();
588:         }
589:     }
590: 
591:     public function SetAttribute($type, $value) {
592:         $attribute_index = -1;
593:         for ($attributes_loop = 0; $attributes_loop < count($this->_attributes_to_send); $attributes_loop++) {
594:             if ($type == ord(substr($this->_attributes_to_send[$attributes_loop], 0, 1))) {
595:                 $attribute_index = $attributes_loop;
596:                 break;
597:             }
598:         }
599:         $temp_attribute = NULL;
600:         if (isset($this->_attributes_info[$type])) {
601:             switch ($this->_attributes_info[$type][1]) {
602:                 case 'T': { // Text, 1-253 octets containing UTF-8 encoded ISO 10646 characters (RFC 2279).
603:                     $temp_attribute = chr($type).chr(2+strlen($value)).$value;
604:                     break;
605:                 }
606:                 case 'S': { // String, 1-253 octets containing binary data (values 0 through 255 decimal, inclusive).
607:                     $temp_attribute = chr($type).chr(2+strlen($value)).$value;
608:                     break;
609:                 }
610:                 case 'A': { // Address, 32 bit value, most significant octet first.
611:                     $ip_array = explode('.', $value);
612:                     $temp_attribute = chr($type).chr(6).chr($ip_array[0]).chr($ip_array[1]).chr($ip_array[2]).chr($ip_array[3]);
613:                     break;
614:                 }
615:                 case 'I': { // Integer, 32 bit unsigned value, most significant octet first.
616:                     $temp_attribute = chr($type).chr(6).chr(($value/(256*256*256))%256).chr(($value/(256*256))%256).chr(($value/(256))%256).chr($value%256);
617:                     break;
618:                 }
619:                 case 'D': { // Time, 32 bit unsigned value, most significant octet first -- seconds since 00:00:00 UTC, January 1, 1970. (not used in this RFC)
620:                     $temp_attribute = NULL;
621:                     break;
622:                 }
623:                 default: {
624:                     $temp_attribute = NULL;
625:                 }
626:             }
627:         }
628:         if ($attribute_index > -1) {
629:             $this->_attributes_to_send[$attribute_index] = $temp_attribute;
630:             $additional_debug = 'Modified';
631:         } else {
632:             $this->_attributes_to_send[] = $temp_attribute;
633:             $additional_debug = 'Added';
634:         }
635:         $attribute_info = $this->GetAttributesInfo($type);
636:         $this->DebugInfo($additional_debug.' Attribute '.$type.' ('.$attribute_info[0].'), format '.$attribute_info[1].', value <em>'.$value.'</em>');
637:     }
638: 
639:     public function DecodeAttribute($attribute_raw_value, $attribute_format) {
640:         $attribute_value = NULL;
641:         if (isset($this->_attributes_info[$attribute_format])) {
642:             switch ($this->_attributes_info[$attribute_format][1]) {
643:                 case 'T': { // Text, 1-253 octets containing UTF-8 encoded ISO 10646 characters (RFC 2279).
644:                     $attribute_value = $attribute_raw_value;
645:                     break;
646:                 }
647:                 case 'S': { // String, 1-253 octets containing binary data (values 0 through 255 decimal, inclusive).
648:                     $attribute_value = $attribute_raw_value;
649:                     break;
650:                 }
651:                 case 'A': { // Address, 32 bit value, most significant octet first.
652:                     $attribute_value = ord(substr($attribute_raw_value, 0, 1)).'.'.ord(substr($attribute_raw_value, 1, 1)).'.'.ord(substr($attribute_raw_value, 2, 1)).'.'.ord(substr($attribute_raw_value, 3, 1));
653:                     break;
654:                 }
655:                 case 'I': { // Integer, 32 bit unsigned value, most significant octet first.
656:                     $attribute_value = (ord(substr($attribute_raw_value, 0, 1))*256*256*256)+(ord(substr($attribute_raw_value, 1, 1))*256*256)+(ord(substr($attribute_raw_value, 2, 1))*256)+ord(substr($attribute_raw_value, 3, 1));
657:                     break;
658:                 }
659:                 case 'D': { // Time, 32 bit unsigned value, most significant octet first -- seconds since 00:00:00 UTC, January 1, 1970. (not used in this RFC)
660:                     $attribute_value = NULL;
661:                     break;
662:                 }
663:                 default: {
664:                     $attribute_value = NULL;
665:                 }
666:             }
667:         }
668:         return $attribute_value;
669:     }
670: 
671:     /*********************************************************************
672:     * Array returned: array(array(Vendor-Id1, Vendor type1, Attribute-Specific1), ..., array(Vendor-IdN, Vendor typeN, Attribute-SpecificN)
673:     *********************************************************************/
674:     public function DecodeVendorSpecificContent($vendor_specific_raw_value) {
675:         $result = array();
676:         $offset_in_raw = 0;
677:         $vendor_id = (ord(substr($vendor_specific_raw_value, 0, 1))*256*256*256)+(ord(substr($vendor_specific_raw_value, 1, 1))*256*256)+(ord(substr($vendor_specific_raw_value, 2, 1))*256)+ord(substr($vendor_specific_raw_value, 3, 1));
678:         $offset_in_raw += 4;
679:         while ($offset_in_raw < strlen($vendor_specific_raw_value)) {
680:             $vendor_type = (ord(substr($vendor_specific_raw_value, 0+$offset_in_raw, 1)));
681:             $vendor_length = (ord(substr($vendor_specific_raw_value, 1+$offset_in_raw, 1)));
682:             $attribute_specific = substr($vendor_specific_raw_value, 2+$offset_in_raw, $vendor_length);
683:             $result[] = array($vendor_id, $vendor_type, $attribute_specific);
684:             $offset_in_raw += ($vendor_length);
685:         }
686:         return $result;
687:     }
688: 
689:     /*
690:     * public function : AccessRequest
691:     *
692:     * Return TRUE if Access-Request is accepted, FALSE otherwise
693:     */
694:     public function AccessRequest($username = '', $password = '', $udp_timeout = 0, $state = NULL) {
695:         $this->ClearDataReceived();
696:         $this->ClearLastError();
697:         $this->SetPacketCodeToSend(1); // Access-Request
698:         if (0 < strlen($username)){
699:             $this->SetUsername($username);
700:         }
701:         if (0 < strlen($password)) {
702:             $this->SetPassword($password);
703:         }
704:         if ($state!==NULL) {
705:             $this->SetAttribute(24, $state);
706:         } else {
707:             $this->SetAttribute(6, 1); // 1=Login
708:         }
709:         if (intval($udp_timeout) > 0) {
710:             $this->SetUdpTimeout($udp_timeout);
711:         }
712:         $attributes_content = '';
713:         for ($attributes_loop = 0; $attributes_loop < count($this->_attributes_to_send); $attributes_loop++) {
714:             $attributes_content .= $this->_attributes_to_send[$attributes_loop];
715:         }
716:         $packet_length = 4; // Radius packet code + Identifier + Length high + Length low
717:         $packet_length += strlen($this->_request_authenticator); // Request-Authenticator
718:         $packet_length += strlen($attributes_content); // Attributes
719:         $packet_data = chr($this->_radius_packet_to_send);
720:         $packet_data .= chr($this->GetNextIdentifier());
721:         $packet_data .= chr(intval($packet_length/256));
722:         $packet_data .= chr(intval($packet_length%256));
723:         $packet_data .= $this->_request_authenticator;
724:         $packet_data .= $attributes_content;
725:         $_socket_to_server = socket_create(AF_INET, SOCK_DGRAM, 17); // UDP packet = 17
726:         if ($_socket_to_server === FALSE) {
727:             $this->_last_error_code = socket_last_error();
728:             $this->_last_error_message = socket_strerror($this->_last_error_code);
729:         } elseif (FALSE === socket_connect($_socket_to_server, $this->_ip_radius_server, $this->_authentication_port)) {
730:             $this->_last_error_code = socket_last_error();
731:             $this->_last_error_message = socket_strerror($this->_last_error_code);
732:         } elseif (FALSE === socket_write($_socket_to_server, $packet_data, $packet_length)) {
733:             $this->_last_error_code = socket_last_error();
734:             $this->_last_error_message = socket_strerror($this->_last_error_code);
735:         } else {
736:             $this->DebugInfo('<b>Packet type '.$this->_radius_packet_to_send.' ('.$this->GetRadiusPacketInfo($this->_radius_packet_to_send).')'.' sent</b>');
737:             if ($this->_debug_mode) {
738:                 $readable_attributes = '';
739:                 foreach($this->_attributes_to_send as $one_attribute_to_send) {
740:                     $attribute_info = $this->GetAttributesInfo(ord(substr($one_attribute_to_send,0,1)));
741:                     $this->DebugInfo('Attribute '.ord(substr($one_attribute_to_send,0,1)).' ('.$attribute_info[0].'), length '.(ord(substr($one_attribute_to_send,1,1))-2).', format '.$attribute_info[1].', value <em>'.$this->DecodeAttribute(substr($one_attribute_to_send,2), ord(substr($one_attribute_to_send,0,1))).'</em>');
742:                 }
743:             }
744:             $read_socket_array = array($_socket_to_server);
745:             $write_socket_array = NULL;
746:             $except_socket_array = NULL;
747:             $received_packet = chr(0);
748:             if (!(FALSE === socket_select($read_socket_array, $write_socket_array, $except_socket_array, $this->_udp_timeout))) {
749:                 if (in_array($_socket_to_server, $read_socket_array)) {
750:                     if (FALSE === ($received_packet = @socket_read($_socket_to_server, 1024))) { // @ used, than no error is displayed if the connection is closed by the remote host
751:                         $received_packet = chr(0);
752:                         $this->_last_error_code = socket_last_error();
753:                         $this->_last_error_message = socket_strerror($this->_last_error_code);
754:                     } else {
755:                         socket_close($_socket_to_server);
756:                     }
757:                 }
758:             } else {
759:                 socket_close($_socket_to_server);
760:             }
761:         }
762:         $this->_radius_packet_received = intval(ord(substr($received_packet, 0, 1)));
763:         $this->DebugInfo('<b>Packet type '.$this->_radius_packet_received.' ('.$this->GetRadiusPacketInfo($this->_radius_packet_received).')'.' received</b>');
764:         if ($this->_radius_packet_received > 0) {
765:             $this->_identifier_received = intval(ord(substr($received_packet, 1, 1)));
766:             $packet_length = (intval(ord(substr($received_packet, 2, 1))) * 256) + (intval(ord(substr($received_packet, 3, 1))));
767:             $this->_response_authenticator = substr($received_packet, 4, 16);
768:             $attributes_content = substr($received_packet, 20, ($packet_length - 4 - 16));
769:             while (strlen($attributes_content) > 2) {
770:                 $attribute_type = intval(ord(substr($attributes_content,0,1)));
771:                 $attribute_length = intval(ord(substr($attributes_content,1,1)));
772:                 $attribute_raw_value = substr($attributes_content,2,$attribute_length-2);
773:                 $attributes_content = substr($attributes_content, $attribute_length);
774:                 $attribute_value = $this->DecodeAttribute($attribute_raw_value, $attribute_type);
775:                 $attribute_info = $this->GetAttributesInfo($attribute_type);
776:                 if (26 == $attribute_type) {
777:                     $vendor_array = $this->DecodeVendorSpecificContent($attribute_value);
778:                     foreach($vendor_array as $vendor_one) {
779:                         $this->DebugInfo('Attribute '.$attribute_type.' ('.$attribute_info[0].'), length '.($attribute_length-2).', format '.$attribute_info[1].', Vendor-Id: '.$vendor_one[0].', Vendor-type: '.$vendor_one[1].', Attribute-specific: '.$vendor_one[2]);
780:                     }
781:                 } else {
782:                     $this->DebugInfo('Attribute '.$attribute_type.' ('.$attribute_info[0].'), length '.($attribute_length-2).', format '.$attribute_info[1].', value <em>'.$attribute_value.'</em>');
783:                 }
784:                 $this->_attributes_received[] = array($attribute_type, $attribute_value);
785:             }
786:         }
787:         return (2 == ($this->_radius_packet_received));
788:     }
789: 
790: } // end of class Radius
791: 
792: //============================================================+
793: // END OF FILE
794: //============================================================+
795: 
 

© 2004-2018 – Nicola Asuni - Tecnick.com - All rights reserved.
about - disclaimer - privacy