Project

General

Profile

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