Projet

Général

Profil

Télécharger (35,7 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / radius.inc @ d2fdc707

1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
/*
4
    $Id$
5

    
6
    Copyright (c) 2003, Michael Bretterklieber <michael@bretterklieber.com>
7
    All rights reserved.
8

    
9
    Redistribution and use in source and binary forms, with or without 
10
    modification, are permitted provided that the following conditions 
11
    are met:
12

    
13
    1. Redistributions of source code must retain the above copyright 
14
       notice, this list of conditions and the following disclaimer.
15
    2. Redistributions in binary form must reproduce the above copyright 
16
       notice, this list of conditions and the following disclaimer in the 
17
       documentation and/or other materials provided with the distribution.
18
    3. The names of the authors may not be used to endorse or promote products 
19
       derived from this software without specific prior written permission.
20

    
21
    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
    EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31

    
32
    This code cannot simply be copied and put under the GNU Public License or 
33
    any other GPL-like (LGPL, GPL2) License.
34

    
35
        This version of RADIUS.php has been modified by
36
        Jonathan De Graeve <m0n0wall@esstec.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
        * Adding of VENDOR ChilliSpot (bandwidth-attributes only)
47

    
48
*/
49

    
50
/*
51
    pfSense_MODULE:    auth
52
*/
53

    
54
require_once("PEAR.inc");
55
require_once("radius_authentication.inc");
56
require_once("radius_accounting.inc");
57

    
58
/**
59
* Client implementation of RADIUS. This are wrapper classes for
60
* the RADIUS PECL
61
* Provides RADIUS Authentication (RFC2865) and RADIUS Accounting (RFC2866).
62
*
63
* @package Auth_RADIUS
64
* @author  Michael Bretterklieber <michael@bretterklieber.com>
65
* @access  public
66
* @version $Revision: 1.5 $
67
*/
68

    
69
PEAR::loadExtension('radius');
70

    
71
/**
72
 * class Auth_RADIUS
73
 *
74
 * Abstract base class for RADIUS
75
 *
76
 * @package Auth_RADIUS 
77
 */
78
class Auth_RADIUS extends PEAR {
79

    
80
    /**
81
     * List of RADIUS servers.
82
     * @var  array
83
     * @see  addServer(), putServer()
84
     */
85
    var $_servers  = array();
86

    
87
    /**
88
     * Path to the configuration-file.
89
     * @var  string
90
     * @see  setConfigFile()
91
     */
92
    var $_configfile = null;
93

    
94
    /**
95
     * Resource.
96
     * @var  resource
97
     * @see  open(), close()
98
     */
99
    var $res = null;
100

    
101
    /**
102
     * Username for authentication and accounting requests.
103
     * @var  string
104
     */
105
    var $username = null;
106

    
107
    /**
108
     * Password for plaintext-authentication (PAP).
109
     * @var  string
110
     */
111
    var $password = null;
112

    
113
    /**
114
     * List of known attributes.
115
     * @var  array
116
     * @see  dumpAttributes(), getAttributes()
117
     */
118
    var $attributes = array();
119

    
120
    /**
121
     * List of raw attributes.
122
     * @var  array
123
     * @see  dumpAttributes(), getAttributes()
124
     */
125
    var $rawAttributes = array();
126

    
127
    /**
128
     * List of raw vendor specific attributes.
129
     * @var  array
130
     * @see  dumpAttributes(), getAttributes()
131
     */
132
    var $rawVendorAttributes = array();
133

    
134
    /**
135
     * Constructor
136
     *
137
     * Loads the RADIUS PECL/extension
138
     *
139
     * @return void
140
     */
141
    function Auth_RADIUS() 
142
    {
143
        $this->PEAR();
144
    }
145

    
146
    /**
147
     * Adds a RADIUS server to the list of servers for requests.
148
     *
149
     * At most 10 servers may be specified.    When multiple servers 
150
     * are given, they are tried in round-robin fashion until a 
151
     * valid response is received
152
     *
153
     * @access public
154
     * @param  string  $servername   Servername or IP-Address
155
     * @param  integer $port         Portnumber
156
     * @param  string  $sharedSecret Shared secret
157
     * @param  integer $timeout      Timeout for each request
158
     * @param  integer $maxtries     Max. retries for each request
159
     * @return void
160
     */
161
    function addServer($servername = 'localhost', $port = 0, $sharedSecret = 'testing123', $timeout = 3, $maxtries = 2) 
162
    {
163
        $this->_servers[] = array($servername, $port, $sharedSecret, $timeout, $maxtries);
164
    }
165

    
166
    /**
167
     * Returns an error message, if an error occurred.
168
     *
169
     * @access public
170
     * @return string
171
     */
172
    function getError() 
173
    {
174
        return radius_strerror($this->res);
175
    }
176

    
177
    /**
178
     * Sets the configuration-file.
179
     *
180
     * @access public
181
     * @param  string  $file Path to the configuration file
182
     * @return void
183
     */
184
    function setConfigfile($file) 
185
    {
186
        $this->_configfile = $file;
187
    }
188

    
189
    /**
190
     * Puts an attribute.
191
     *
192
     * @access public
193
     * @param  integer $attrib       Attribute-number
194
     * @param  mixed   $port         Attribute-value
195
     * @param  type    $type         Attribute-type
196
     * @return bool  true on success, false on error
197
     */
198
    function putAttribute($attrib, $value, $type = null) 
199
    {
200
        if ($type == null) {
201
            $type = gettype($value);
202
        }
203

    
204
        switch ($type) {
205
        case 'integer':
206
            // Fix a conversion error so we should be able to handle 4GB values
207
            return radius_put_int($this->res, $attrib, (float)$value);
208

    
209
        case 'addr':
210
            return radius_put_addr($this->res, $attrib, $value);
211

    
212
        case 'string':
213
        default:
214
            return radius_put_attr($this->res, $attrib, $value);
215
        }
216

    
217
    }
218

    
219
    /**
220
     * Puts a vendor-specific attribute.
221
     *
222
     * @access public
223
     * @param  integer $vendor       Vendor (MSoft, Cisco, ...)
224
     * @param  integer $attrib       Attribute-number
225
     * @param  mixed   $port         Attribute-value
226
     * @param  type    $type         Attribute-type
227
     * @return bool  true on success, false on error
228
     */ 
229
    function putVendorAttribute($vendor, $attrib, $value, $type = null) 
230
    {
231

    
232
        if ($type == null) {
233
            $type = gettype($value);
234
        }
235

    
236
        switch ($type) {
237
        case 'integer':
238
            return radius_put_vendor_int($this->res, $vendor, $attrib, $value);
239

    
240
        case 'addr':
241
            return radius_put_vendor_addr($this->res, $vendor,$attrib, $value);
242

    
243
        case 'string':
244
        default:
245
            return radius_put_vendor_attr($this->res, $vendor, $attrib, $value);
246
        }
247

    
248
    }
249

    
250
    /**
251
     * Prints known attributes received from the server.
252
     *
253
     * @access public
254
     */
255
    function dumpAttributes()
256
    {
257
        foreach ($this->attributes as $name => $data) {
258
            echo "$name:$data<br />\n";
259
        }
260
    }
261

    
262
    /**
263
     * Return our know attributes array received from the server.
264
     *
265
     * @access public
266
     */
267
    function listAttributes()
268
    {
269
        return $this->attributes;
270
    }
271

    
272
    /**
273
     * Overwrite this. 
274
     *
275
     * @access public
276
     */
277
    function open() 
278
    {
279
    }
280

    
281
    /**
282
     * Overwrite this.
283
     *
284
     * @access public
285
     */
286
    function createRequest()
287
    {
288
    }
289

    
290
    /**
291
     * Puts standard attributes.
292
     *
293
     * These attributes will always be present in a radius request
294
     *
295
     * @access public
296
     */
297
    function putStandardAttributes()
298
    {
299
        global $config, $cpzone;
300

    
301
        if (!function_exists("getNasIp")) {
302
            $ipaddr = "0.0.0.0";
303
        } else {
304
            $ipaddr = getNasIP();
305
        }
306
        // Add support for sending NAS-IP-Address, set this explicitly as an ip_addr
307
        $this->putAttribute(RADIUS_NAS_IP_ADDRESS, $ipaddr, "addr");
308

    
309
        // Add support for sending NAS-Identifier
310
        if (empty($config["captiveportal"][$cpzone]["radiusnasid"])) {
311
            $nasId = php_uname("n");
312
        } else {
313
            $nasId = $config["captiveportal"][$cpzone]["radiusnasid"];
314
        }
315
        $this->putAttribute(RADIUS_NAS_IDENTIFIER, $nasId);
316
    }
317

    
318
    /**
319
     * Puts custom attributes.
320
     *
321
     * @access public
322
     */
323
    function putAuthAttributes()
324
    {
325
        if (isset($this->username)) {
326
            $this->putAttribute(RADIUS_USER_NAME, $this->username);
327
        }
328
    }
329

    
330
    /**
331
     * Configures the radius library.
332
     *
333
     * @access public
334
     * @param  string  $servername   Servername or IP-Address
335
     * @param  integer $port         Portnumber
336
     * @param  string  $sharedSecret Shared secret
337
     * @param  integer $timeout      Timeout for each request
338
     * @param  integer $maxtries     Max. retries for each request
339
     * @return bool  true on success, false on error
340
     * @see addServer()
341
     */
342
    function putServer($servername, $port = 0, $sharedsecret = 'testing123', $timeout = 3, $maxtries = 3) 
343
    {
344
        if (!radius_add_server($this->res, $servername, $port, $sharedsecret, $timeout, $maxtries)) {
345
            return false;
346
        }
347
        return true;
348
    }
349

    
350
    /**
351
     * Configures the radius library via external configurationfile
352
     *
353
     * @access public
354
     * @param  string  $servername   Servername or IP-Address
355
     * @return bool  true on success, false on error
356
     */
357
    function putConfigfile($file) 
358
    {
359
        if (!radius_config($this->res, $file)) {
360
            return false;
361
        }
362
        return true;
363
    }
364

    
365
    /**
366
     * Initiates a RADIUS request. 
367
     *
368
     * @access public
369
     * @return bool  true on success, false on errors     
370
     */ 
371
    function start()
372
    {
373
        if (!$this->open()) {
374
            return false;
375
        }
376

    
377
        foreach ($this->_servers as $s) {
378
            // Servername, port, sharedsecret, timeout, retries
379
            if (!$this->putServer($s[0], $s[1], $s[2], $s[3], $s[4])) {
380
                return false;
381
            }
382
        }
383

    
384
        if (!empty($this->_configfile)) {
385
            if (!$this->putConfigfile($this->_configfile)) {
386
                return false;
387
            }
388
        }
389

    
390
        $this->createRequest();
391
        $this->putStandardAttributes();
392
        $this->putAuthAttributes();
393
        return true;
394
    }
395

    
396
    /**
397
     * Sends a prepared RADIUS request and waits for a response
398
     *
399
     * @access public
400
     * @return mixed  true on success, false on reject, PEAR_Error on error
401
     */
402
    function send()
403
    {
404
        $req = radius_send_request($this->res);
405
        if (!$req) {
406
            return $this->raiseError(gettext('Error sending request:') . ' ' . $this->getError());
407
        }
408

    
409
        switch($req) {
410
        case RADIUS_ACCESS_ACCEPT:
411
            if (is_subclass_of($this, 'auth_radius_acct')) {
412
                return $this->raiseError(gettext('RADIUS_ACCESS_ACCEPT is unexpected for accounting'));
413
            }
414
            return true;
415

    
416
        case RADIUS_ACCESS_REJECT:
417
            return false;
418

    
419
        case RADIUS_ACCOUNTING_RESPONSE:
420
            if (is_subclass_of($this, 'auth_radius_pap')) {
421
                return $this->raiseError(gettext('RADIUS_ACCOUNTING_RESPONSE is unexpected for authentication'));
422
            }
423
            return true;
424

    
425
        default:
426
            return $this->raiseError(sprintf(gettext("Unexpected return value: %s"),$req));
427
        }
428

    
429
    }
430

    
431
    /**
432
     * Reads all received attributes after sending the request.
433
     *
434
     * This methos stores know attributes in the property attributes,
435
     * all attributes (including known attibutes) are stored in rawAttributes
436
     * or rawVendorAttributes.
437
     * NOTE: call this functio also even if the request was rejected, because the
438
     * Server returns usualy an errormessage
439
     *
440
     * @access public
441
     * @return bool   true on success, false on error
442
     */
443
    function getAttributes()
444
    {
445

    
446
        while ($attrib = radius_get_attr($this->res)) {
447

    
448
            if (!is_array($attrib)) {
449
                return false;
450
            }        
451

    
452
            $attr = $attrib['attr'];
453
            $data = $attrib['data'];
454

    
455
            $this->rawAttributes[$attr] = $data;
456

    
457
            switch ($attr) {
458
            case RADIUS_FRAMED_IP_ADDRESS:
459
                $this->attributes['framed_ip'] = radius_cvt_addr($data);
460
                break;
461

    
462
            case RADIUS_FRAMED_IP_NETMASK:
463
                $this->attributes['framed_mask'] = radius_cvt_addr($data);
464
                break;
465

    
466
            case RADIUS_FRAMED_MTU:
467
                $this->attributes['framed_mtu'] = radius_cvt_int($data);
468
                break;
469

    
470
            case RADIUS_FRAMED_COMPRESSION:
471
                $this->attributes['framed_compression'] = radius_cvt_int($data);
472
                break;
473

    
474
            case RADIUS_SESSION_TIMEOUT:
475
                $this->attributes['session_timeout'] = radius_cvt_int($data);
476
                break;
477

    
478
            case RADIUS_IDLE_TIMEOUT:
479
                $this->attributes['idle_timeout'] = radius_cvt_int($data);
480
                break;
481

    
482
            case RADIUS_SERVICE_TYPE:
483
                $this->attributes['service_type'] = radius_cvt_int($data);
484
                break;
485

    
486
            case RADIUS_CLASS:
487
                $this->attributes['class'] = radius_cvt_int($data);
488
                break;
489

    
490
            case RADIUS_FRAMED_PROTOCOL:
491
                $this->attributes['framed_protocol'] = radius_cvt_int($data);
492
                break;
493

    
494
            case RADIUS_FRAMED_ROUTING:
495
                $this->attributes['framed_routing'] = radius_cvt_int($data);
496
                break;
497

    
498
            case RADIUS_FILTER_ID:
499
                $this->attributes['filter_id'] = radius_cvt_string($data);
500
                break;
501

    
502
            case RADIUS_REPLY_MESSAGE:
503
                $this->attributes['reply_message'] = radius_cvt_string($data);
504
                break;
505

    
506
            case RADIUS_VENDOR_SPECIFIC:
507
                $attribv = radius_get_vendor_attr($data);
508
                if (!is_array($attribv)) {
509
                    return false;
510
                }
511

    
512
                $vendor = $attribv['vendor'];
513
                $attrv = $attribv['attr'];
514
                $datav = $attribv['data'];
515

    
516
                $this->rawVendorAttributes[$vendor][$attrv] = $datav;
517

    
518
                if ($vendor == RADIUS_VENDOR_MICROSOFT) {
519

    
520
                    switch ($attrv) {
521
                    case RADIUS_MICROSOFT_MS_CHAP2_SUCCESS:
522
                        $this->attributes['ms_chap2_success'] = radius_cvt_string($datav);
523
                        break;
524

    
525
                    case RADIUS_MICROSOFT_MS_CHAP_ERROR:
526
                        $this->attributes['ms_chap_error'] = radius_cvt_string(substr($datav,1));
527
                        break;
528

    
529
                    case RADIUS_MICROSOFT_MS_CHAP_DOMAIN:
530
                        $this->attributes['ms_chap_domain'] = radius_cvt_string($datav);
531
                        break;
532

    
533
                    case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
534
                        $this->attributes['ms_mppe_encryption_policy'] = radius_cvt_int($datav);
535
                        break;
536

    
537
                    case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
538
                        $this->attributes['ms_mppe_encryption_types'] = radius_cvt_int($datav);
539
                        break;
540

    
541
                    case RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS:
542
                        $demangled = radius_demangle($this->res, $datav);
543
                        $this->attributes['ms_chap_mppe_lm_key'] = substr($demangled, 0, 8);
544
                        $this->attributes['ms_chap_mppe_nt_key'] = substr($demangled, 8, RADIUS_MPPE_KEY_LEN);
545
                        break;
546

    
547
                    case RADIUS_MICROSOFT_MS_MPPE_SEND_KEY:
548
                        $this->attributes['ms_chap_mppe_send_key'] = radius_demangle_mppe_key($this->res, $datav);
549
                        break;
550

    
551
                    case RADIUS_MICROSOFT_MS_MPPE_RECV_KEY:
552
                        $this->attributes['ms_chap_mppe_recv_key'] = radius_demangle_mppe_key($this->res, $datav);
553
                        break;
554

    
555
                    case RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER:
556
                        $this->attributes['ms_primary_dns_server'] = radius_cvt_string($datav);
557
                        break;
558
                    }
559
                }
560

    
561
                elseif ($vendor == 1584) {
562

    
563
                    switch ($attrv) {
564
                    case 102:
565
                        $this->attributes['ces_group'] = radius_cvt_string($datav);
566
                        break;
567
                    }
568
                }
569

    
570
                elseif ($vendor == 3309) {    /* RADIUS_VENDOR_NOMADIX */
571

    
572
                    switch ($attrv) {
573
                    case 1: /* RADIUS_NOMADIX_BW_UP */
574
                        $this->attributes['bw_up'] = radius_cvt_int($datav);
575
                        break;
576
                    case 2: /* RADIUS_NOMADIX_BW_DOWN */
577
                        $this->attributes['bw_down'] = radius_cvt_int($datav);
578
                        break;
579
                    case 3: /* RADIUS_NOMADIX_URL_REDIRECTION */
580
                        $this->attributes['url_redirection'] = radius_cvt_string($datav);
581
                        break;
582
                    case 5: /* RADIUS_NOMADIX_EXPIRATION */
583
                        $this->attributes['expiration'] = radius_cvt_string($datav);
584
                        break;
585
                    case 7: /* RADIUS_NOMADIX_MAXBYTESUP */
586
                        $this->attributes['maxbytesup'] = radius_cvt_int($datav);
587
                        break;
588
                    case 8: /* RADIUS_NOMADIX_MAXBYTESDOWN */
589
                        $this->attributes['maxbytesdown'] = radius_cvt_int($datav);
590
                        break;
591
                    case 10: /* RADIUS_NOMADIX_LOGOFF_URL */
592
                        $this->attributes['url_logoff'] = radius_cvt_string($datav);
593
                        break;
594
                    }
595
                } 
596

    
597
                elseif ($vendor == 14122) { /* RADIUS_VENDOR_WISPr Wi-Fi Alliance */
598

    
599
                    switch ($attrv) {
600
                    case 1: /* WISPr-Location-ID */
601
                        $this->attributes['location_id'] = radius_cvt_string($datav);
602
                        break;
603
                    case 2: /* WISPr-Location-Name */
604
                        $this->attributes['location_name'] = radius_cvt_string($datav);
605
                        break;
606
                    case 3: /* WISPr-Logoff-URL */
607
                        $this->attributes['url_logoff'] = radius_cvt_string($datav);
608
                        break;
609
                    case 4: /* WISPr-Redirection-URL */
610
                        $this->attributes['url_redirection'] = radius_cvt_string($datav);
611
                        break;
612
                    case 5: /* WISPr-Bandwidth-Min-Up */
613
                        $this->attributes['bw_up_min'] = radius_cvt_int($datav);
614
                        break;
615
                    case 6: /* WISPr-Bandwidth-Min-Down */
616
                        $this->attributes['bw_down_min'] = radius_cvt_int($datav);
617
                        break;
618
                    case 7: /* WISPr-Bandwidth-Max-Up */
619
                        $this->attributes['bw_up'] = radius_cvt_int($datav);
620
                        break;
621
                    case 8: /* WISPr-Bandwidth-Max-Down */
622
                        $this->attributes['bw_down'] = radius_cvt_int($datav);
623
                        break;
624
                    case 9: /* WISPr-Session-Terminate-Time */
625
                        $this->attributes['session_terminate_time'] = radius_cvt_string($datav);
626
                        break;
627
                    case 10: /* WISPr-Session-Terminate-End-Of-Day */
628
                        $this->attributes['session_terminate_endofday'] = radius_cvt_int($datav);
629
                        break;
630
                    case 11: /* WISPr-Billing-Class-Of-Service */
631
                        $this->attributes['billing_class_of_service'] = radius_cvt_string($datav);
632
                        break;
633
                    }
634
                }
635

    
636
                elseif ($vendor == 14559) { /* RADIUS_VENDOR_ChilliSpot */
637
                    switch ($attrv) {
638
                    case 4: /* ChilliSpot-Bandwidth-Max-Up */
639
                        $this->attributes['bw_up'] = radius_cvt_int($datav);
640
                        break;
641
                    case 5: /* ChilliSpot-Bandwidth-Max-Down */
642
                        $this->attributes['bw_down'] = radius_cvt_int($datav);
643
                        break;
644
                    }
645
                }
646

    
647
		elseif ($vendor == 9) { /* RADIUS_VENDOR_CISCO */
648
			switch ($attrv) {
649
			case 1: /* Cisco-AVPair */
650
				if (!is_array($this->attributes['ciscoavpair']))
651
					$this->attributes['ciscoavpair'] = array();
652
				$this->attributes['ciscoavpair'][] = radius_cvt_string($datav);
653
				break;
654
			}
655
		}
656

    
657
                elseif ($vendor == 8744) { /* Colubris / HP MSM wireless */
658
                    //documented at http://bizsupport1.austin.hp.com/bc/docs/support/SupportManual/c02704528/c02704528.pdf pg 15-67
659
                    if ($attrv == 0) { /* Colubris AV-Pair */
660
                        $datav = explode('=', $datav);
661
                        switch ($datav[0]) {
662
                        case 'max-input-rate':
663
                            // "Controls the data rate [kbps] at which traffic can be transferred from the user to the [router]."
664
                            $this->attributes['bw_up'] = radius_cvt_int($datav[1]);
665
                            break;
666
                        case 'max-output-rate':
667
                            //"Controls the data rate [kbps] at which traffic can be transferred from the [router] to the user."
668
                            $this->attributes['bw_down'] = radius_cvt_int($datav[1]);
669
                            break;
670
                        case 'max-input-octets':
671
                            $this->attributes['maxbytesup'] = radius_cvt_int($datav[1]);
672
                            break;
673
                        case 'max-output-octets':
674
                            $this->attributes['maxbytesdown'] = radius_cvt_int($datav[1]);
675
                            break;
676
                        case 'welcome-url':
677
                            $this->attributes['url_redirection'] = radius_cvt_string($datav[1]);
678
                            break;
679
                        case 'goodbye-url':
680
                            $this->attributes['url_logoff'] = radius_cvt_string($datav[1]);
681
                            break;
682
                        }
683
                    }
684
                }
685

    
686
                break;
687

    
688
            case 85: /* Acct-Interim-Interval: RFC 2869 */
689
                $this->attributes['interim_interval'] = radius_cvt_int($data);
690
                break;
691
            }
692
        }
693

    
694
        return true;
695
    }
696

    
697
    /**
698
     * Frees resources.
699
     *
700
     * Calling this method is always a good idea, because all security relevant
701
     * attributes are filled with Nullbytes to leave nothing in the mem.
702
     *
703
     * @access public
704
     */
705
    function close()
706
    {
707
        if ($this->res != null) {
708
            radius_close($this->res);
709
            $this->res = null;
710
        }
711
        $this->username = str_repeat("\0", strlen($this->username));
712
        $this->password = str_repeat("\0", strlen($this->password));
713
    }
714

    
715
}
716

    
717
/**
718
 * class Auth_RADIUS_PAP
719
 *
720
 * Class for authenticating using PAP (Plaintext)
721
 *
722
 * @package Auth_RADIUS 
723
 */
724
class Auth_RADIUS_PAP extends Auth_RADIUS 
725
{
726

    
727
    /**
728
     * Constructor
729
     *
730
     * @param  string  $username   Username
731
     * @param  string  $password   Password
732
     * @return void
733
     */
734
    function Auth_RADIUS_PAP($username = null, $password = null)
735
    {
736
        $this->Auth_RADIUS();
737
        $this->username = $username;
738
        $this->password = $password;
739
    }
740

    
741
    /**
742
     * Creates a RADIUS resource
743
     *
744
     * Creates a RADIUS resource for authentication. This should be the first
745
     * call before you make any other things with the library.
746
     *
747
     * @return bool   true on success, false on error
748
     */
749
    function open() 
750
    {
751
        $this->res = radius_auth_open();
752
        if (!$this->res) {
753
            return false;
754
        }
755
        return true;
756
    }
757

    
758
    /**
759
     * Creates an authentication request 
760
     *
761
     * Creates an authentication request.
762
     * You MUST call this method before you can put any attribute
763
     *
764
     * @return bool   true on success, false on error
765
     */
766
    function createRequest()
767
    {
768
        if (!radius_create_request($this->res, RADIUS_ACCESS_REQUEST)) {
769
            return false;
770
        }
771
        return true;
772
    }
773

    
774
    /**
775
     * Put authentication specific attributes 
776
     *
777
     * @return void
778
     */
779
    function putAuthAttributes()
780
    {
781
        if (isset($this->username)) {
782
            $this->putAttribute(RADIUS_USER_NAME, $this->username);
783
        }
784
        if (isset($this->password)) {
785
            $this->putAttribute(RADIUS_USER_PASSWORD, $this->password);
786
        }
787
    }
788

    
789
}
790

    
791
/**
792
 * class Auth_RADIUS_CHAP_MD5
793
 *
794
 * Class for authenticating using CHAP-MD5 see RFC1994.
795
 * Instead og the plaintext password the challenge and 
796
 * the response are needed.
797
 *
798
 * @package Auth_RADIUS 
799
 */
800
class Auth_RADIUS_CHAP_MD5 extends Auth_RADIUS_PAP
801
{
802
    /**
803
     * 8 Bytes binary challenge
804
     * @var  string
805
     */
806
    var $challenge = null;
807

    
808
    /**
809
     * 16 Bytes MD5 response binary
810
     * @var  string
811
     */
812
    var $response = null;
813

    
814
    /**
815
     * Id of the authentication request. Should incremented after every request.
816
     * @var  integer
817
     */
818
    var $chapid = 1;
819

    
820
    /**
821
     * Constructor
822
     *
823
     * @param  string  $username   Username
824
     * @param  string  $challenge  8 Bytes Challenge (binary)
825
     * @param  integer $chapid     Requestnumber
826
     * @return void
827
     */
828
    function Auth_RADIUS_CHAP_MD5($username = null, $challenge = null, $chapid = 1)
829
    {
830
        $this->Auth_RADIUS_PAP();
831
        $this->username = $username;
832
        $this->challenge = $challenge;
833
        $this->chapid = $chapid;
834
    }
835

    
836
    /**
837
     * Put CHAP-MD5 specific attributes
838
     *
839
     * For authenticating using CHAP-MD5 via RADIUS you have to put the challenge 
840
     * and the response. The chapid is inserted in the first byte of the response.
841
     *
842
     * @return void
843
     */
844
    function putAuthAttributes()
845
    {
846
        if (isset($this->username)) {
847
            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
848
        }
849
        if (isset($this->response)) {
850
            $response = pack('C', $this->chapid) . $this->response;
851
            $this->putAttribute(RADIUS_CHAP_PASSWORD, $response);
852
        }
853
        if (isset($this->challenge)) {
854
            $this->putAttribute(RADIUS_CHAP_CHALLENGE, $this->challenge);
855
        }
856
    }
857

    
858
    /**
859
     * Frees resources.
860
     *
861
     * Calling this method is always a good idea, because all security relevant
862
     * attributes are filled with Nullbytes to leave nothing in the mem.
863
     *
864
     * @access public
865
     */
866
    function close()
867
    {
868
        Auth_RADIUS_PAP::close();
869
        $this->challenge =  str_repeat("\0", strlen($this->challenge));
870
        $this->response =  str_repeat("\0", strlen($this->response));
871
    }
872

    
873
}
874

    
875
/**
876
 * class Auth_RADIUS_MSCHAPv1
877
 *
878
 * Class for authenticating using MS-CHAPv1 see RFC2433
879
 *
880
 * @package Auth_RADIUS 
881
 */
882
class Auth_RADIUS_MSCHAPv1 extends Auth_RADIUS_CHAP_MD5 
883
{
884
    /**
885
     * LAN-Manager-Response
886
     * @var  string
887
     */
888
    var $lmResponse = null;
889

    
890
    /**
891
     * Wether using deprecated LM-Responses or not.
892
     * 0 = use LM-Response, 1 = use NT-Response
893
     * @var  bool
894
     */
895
    var $flags = 1;
896

    
897
    /**
898
     * Put MS-CHAPv1 specific attributes 
899
     *
900
     * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge 
901
     * and the response. The response has this structure:
902
     * struct rad_mschapvalue {
903
     *   u_char ident;
904
     *   u_char flags;
905
     *   u_char lm_response[24];
906
     *   u_char response[24];
907
     * };
908
     *
909
     * @return void
910
     */
911
    function putAuthAttributes()
912
    {
913
        if (isset($this->username)) {
914
            $this->putAttribute(RADIUS_USER_NAME, $this->username);
915
        }
916
        if (isset($this->response) || isset($this->lmResponse)) {
917
            $lmResp = isset($this->lmResponse) ? $this->lmResponse : str_repeat ("\0", 24);
918
            $ntResp = isset($this->response)   ? $this->response :   str_repeat ("\0", 24);
919
            $resp = pack('CC', $this->chapid, $this->flags) . $lmResp . $ntResp;
920
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_RESPONSE, $resp);
921
        }
922
        if (isset($this->challenge)) {
923
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
924
        }
925
    }
926
}
927

    
928
/**
929
 * class Auth_RADIUS_MSCHAPv2
930
 *
931
 * Class for authenticating using MS-CHAPv2 see RFC2759
932
 *
933
 * @package Auth_RADIUS 
934
 */
935
class Auth_RADIUS_MSCHAPv2 extends Auth_RADIUS_MSCHAPv1 
936
{
937
    /**
938
     * 16 Bytes binary challenge
939
     * @var  string
940
     */
941
    var $challenge = null;
942

    
943
    /**
944
     * 16 Bytes binary Peer Challenge
945
     * @var  string
946
     */
947
    var $peerChallenge = null;
948

    
949
  /**
950
     * Put MS-CHAPv2 specific attributes 
951
     *
952
     * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge 
953
     * and the response. The response has this structure:
954
     * struct rad_mschapv2value {
955
     *   u_char ident;
956
     *   u_char flags;
957
     *   u_char pchallenge[16];
958
     *   u_char reserved[8];
959
     *   u_char response[24];
960
     * };
961
     * where pchallenge is the peer challenge. Like for MS-CHAPv1 we set the flags field to 1.
962
     * @return void
963
     */
964
    function putAuthAttributes()
965
    {
966
        if (isset($this->username)) {
967
            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
968
        }
969
        if (isset($this->response) && isset($this->peerChallenge)) {
970
            // Response: chapid, flags (1 = use NT Response), Peer challenge, reserved, Response        
971
            $resp = pack('CCa16a8a24',$this->chapid , 1, $this->peerChallenge, str_repeat("\0", 8), $this->response);        
972
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP2_RESPONSE, $resp);
973
        }
974
        if (isset($this->challenge)) {
975
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
976
        }
977
    }
978

    
979
    /**
980
     * Frees resources.
981
     *
982
     * Calling this method is always a good idea, because all security relevant
983
     * attributes are filled with Nullbytes to leave nothing in the mem.
984
     *
985
     * @access public
986
     */   
987
    function close()
988
    {
989
        Auth_RADIUS_MSCHAPv1::close();
990
        $this->peerChallenge = str_repeat("\0", strlen($this->peerChallenge));
991
    }
992
}
993

    
994
/**
995
 * class Auth_RADIUS_Acct
996
 *
997
 * Class for RADIUS accounting
998
 * 
999
 * @package Auth_RADIUS 
1000
 */
1001
class Auth_RADIUS_Acct extends Auth_RADIUS 
1002
{
1003
    /**
1004
     * Defines where the Authentication was made, possible values are:
1005
     * RADIUS_AUTH_RADIUS, RADIUS_AUTH_LOCAL, RADIUS_AUTH_REMOTE
1006
     * @var  integer
1007
     */
1008
    var $authentic = null;
1009

    
1010
   /**
1011
     * Defines the type of the accounting request, on of:
1012
     * RADIUS_START, RADIUS_STOP, RADIUS_ACCOUNTING_ON, RADIUS_ACCOUNTING_OFF
1013
     * @var  integer
1014
     */    
1015
    var $status_type = null;
1016

    
1017
   /**
1018
     * The time the user was logged in in seconds
1019
     * @var  integer
1020
     */    
1021
    var $session_time = null;
1022

    
1023
   /**
1024
     * A uniq identifier for the session of the user, maybe the PHP-Session-Id
1025
     * @var  string
1026
     */    
1027
    var $session_id = null;
1028

    
1029
    /**
1030
     * Constructor
1031
     *
1032
     * This function is disabled for M0n0wall since we use our own session_id
1033
     *
1034
     * Generates a predefined session_id. We use the Remote-Address, the PID, and the Current user.
1035
     * @return void
1036
     *
1037
    function Auth_RADIUS_Acct()
1038
    {
1039
        $this->Auth_RADIUS();
1040

    
1041
        if (isset($_SERVER)) {
1042
            $var = &$_SERVER;
1043
        } else {
1044
            $var = &$GLOBALS['HTTP_SERVER_VARS'];
1045
        }
1046

    
1047
        $this->session_id = sprintf("%s:%d-%s", isset($var['REMOTE_ADDR']) ? $var['REMOTE_ADDR'] : '127.0.0.1' , getmypid(), get_current_user());
1048
    }
1049
    */
1050

    
1051
    /**
1052
     * Constructor
1053
     *
1054
     */
1055

    
1056
    function Auth_RADIUS_Acct()
1057
    {
1058
        $this->Auth_RADIUS();
1059
    }
1060

    
1061
    /**
1062
     * Creates a RADIUS resource
1063
     *
1064
     * Creates a RADIUS resource for accounting. This should be the first
1065
     * call before you make any other things with the library.
1066
     *
1067
     * @return bool   true on success, false on error
1068
     */
1069
    function open() 
1070
    {
1071
        $this->res = radius_acct_open();
1072
        if (!$this->res) {
1073
            return false;
1074
        }
1075
        return true;
1076
    }
1077

    
1078
   /**
1079
     * Creates an accounting request 
1080
     *
1081
     * Creates an accounting request.
1082
     * You MUST call this method before you can put any attribute.
1083
     *
1084
     * @return bool   true on success, false on error
1085
     */
1086
    function createRequest()
1087
    {
1088
        if (!radius_create_request($this->res, RADIUS_ACCOUNTING_REQUEST)) {
1089
            return false;
1090
        }
1091
        return true;
1092
    }
1093

    
1094
  /**
1095
     * Put attributes for accounting.
1096
     *
1097
     * Here we put some accounting values. There many more attributes for accounting, 
1098
     * but for web-applications only certain attributes make sense.
1099
     * @return void
1100
     */ 
1101
    function putAuthAttributes()
1102
    {
1103
        if (isset($this->username)) {
1104
            $this->putAttribute(RADIUS_USER_NAME, $this->username);
1105
        }
1106
        $this->putAttribute(RADIUS_ACCT_STATUS_TYPE, $this->status_type);
1107
        //if (isset($this->session_time) && $this->status_type == RADIUS_STOP) {
1108
        if (isset($this->session_time)) {
1109
            $this->putAttribute(RADIUS_ACCT_SESSION_TIME, $this->session_time);
1110
        }
1111
        if (isset($this->authentic)) {
1112
            $this->putAttribute(RADIUS_ACCT_AUTHENTIC, $this->authentic);
1113
        }
1114

    
1115
        $this->putStandardAttributes();
1116
    }
1117

    
1118
}
1119

    
1120
/**
1121
 * class Auth_RADIUS_Acct_Start
1122
 *
1123
 * Class for RADIUS accounting. Its usualy used, after the user has logged in.
1124
 * 
1125
 * @package Auth_RADIUS
1126
 */
1127
class Auth_RADIUS_Acct_Start extends Auth_RADIUS_Acct 
1128
{
1129
   /**
1130
     * Defines the type of the accounting request.
1131
     * It is set to RADIUS_START by default in this class.
1132
     * @var  integer
1133
     */
1134
    var $status_type = RADIUS_START;
1135
}
1136

    
1137
/**
1138
 * class Auth_RADIUS_Acct_Start
1139
 *
1140
 * Class for RADIUS accounting. Its usualy used, after the user has logged out.
1141
 *
1142
 * @package Auth_RADIUS
1143
 */
1144
class Auth_RADIUS_Acct_Stop extends Auth_RADIUS_Acct
1145
{
1146
   /**
1147
     * Defines the type of the accounting request.
1148
     * It is set to RADIUS_STOP by default in this class.
1149
     * @var  integer
1150
     */
1151
    var $status_type = RADIUS_STOP;
1152
}
1153

    
1154
if (!defined('RADIUS_UPDATE'))
1155
    define('RADIUS_UPDATE', 3);
1156

    
1157
/**
1158
 * class Auth_RADIUS_Acct_Update
1159
 *
1160
 * Class for interim RADIUS accounting updates.
1161
 *
1162
 * @package Auth_RADIUS
1163
 */
1164
class Auth_RADIUS_Acct_Update extends Auth_RADIUS_Acct
1165
{
1166
   /**
1167
     * Defines the type of the accounting request.
1168
     * It is set to RADIUS_UPDATE by default in this class.
1169
     * @var  integer
1170
     */
1171
    var $status_type = RADIUS_UPDATE;
1172
}
1173

    
1174
/**
1175
 * class Auth_RADIUS_Acct_On
1176
 *
1177
 * Class for sending Accounting-On updates
1178
 *
1179
 * @package Auth_RADIUS
1180
 */
1181
class Auth_RADIUS_Acct_On extends Auth_RADIUS_Acct
1182
{
1183
    /**
1184
      * Defines the type of the accounting request.
1185
      * It is set to RADIUS_ACCOUNTING_ON by default in this class.
1186
      * @var  integer
1187
      */
1188
    var $status_type = RADIUS_ACCOUNTING_ON;
1189
}
1190

    
1191
/**
1192
 * class Auth_RADIUS_Acct_Off
1193
 *
1194
 * Class for sending Accounting-Off updates
1195
 *
1196
 * @package Auth_RADIUS
1197
 */
1198
class Auth_RADIUS_Acct_Off extends Auth_RADIUS_Acct
1199
{
1200
    /**
1201
      * Defines the type of the accounting request.
1202
      * It is set to RADIUS_ACCOUNTING_OFF by default in this class.
1203
      * @var  integer
1204
      */
1205
    var $status_type = RADIUS_ACCOUNTING_OFF;
1206
}
1207

    
1208
?>
(46-46/68)