Project

General

Profile

Download (31.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
/*
4
Copyright (c) 2003, Michael Bretterklieber <michael@bretterklieber.com>
5
All rights reserved.
6

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

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

    
19
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
20
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
21
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
22
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
23
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
24
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
25
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
26
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
27
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
28
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29

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

    
33
    $Id$
34

    
35
    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
    $Id_jdg: 2005/12/22 14:22:42
39

    
40
    Changes made include:
41
    * StandardAttributes for M0n0wall use
42
    * Removed internal Session-Id creation
43
    * Adding of ReplyMessage to getAttributes()
44
    * Adding of listAttributes()
45
    * Adding of VENDOR Bay Networks (Nortel)
46
    * Adding of VENDOR Nomadix
47
    * Adding of VENDOR WISPr (Wi-Fi Alliance)
48
    
49
*/
50

    
51
require_once("PEAR.inc");
52

    
53
/**
54
* Client implementation of RADIUS. This are wrapper classes for
55
* the RADIUS PECL. 
56
* 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
 * @package Auth_RADIUS 
72
 */
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
    
82
    /**
83
     * Path to the configuration-file.
84
     * @var  string
85
     * @see  setConfigFile()
86
     */
87
    var $_configfile = null;
88
    
89
    /**
90
     * Resource.
91
     * @var  resource
92
     * @see  open(), close()
93
     */
94
    var $res = null;
95
    
96
    /**
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
    
115
    /**
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
    var $rawVendorAttributes = array();    
128
    
129
    /**
130
     * Constructor
131
     *
132
     * Loads the RADIUS PECL/extension
133
     *
134
     * @return void
135
     */
136
    function Auth_RADIUS() 
137
    {
138
        $this->PEAR();
139
    }
140
    
141
    /**
142
     * Adds a RADIUS server to the list of servers for requests.
143
     *
144
     * At most 10 servers may be specified.	When multiple servers 
145
     * are given, they are tried in round-robin fashion until a 
146
     * 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
     * @param  integer $maxtries     Max. retries for each request          
154
     * @return void
155
     */
156
    function addServer($servername = 'localhost', $port = 0, $sharedSecret = 'testing123', $timeout = 5, $maxtries = 3) 
157
    {
158
        $this->_servers[] = array($servername, $port, $sharedSecret, $timeout, $maxtries);    
159
    }
160
    
161
    /**
162
     * Returns an error message, if an error occurred.
163
     *
164
     * @access public
165
     * @return string
166
     */
167
    function getError() 
168
    {
169
        return radius_strerror($this->res);
170
    }
171
    
172
    /**
173
     * Sets the configuration-file.
174
     *
175
     * @access public
176
     * @param  string  $file Path to the configuration file    
177
     * @return void
178
     */    
179
    function setConfigfile($file) 
180
    {
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
     */    
193
    function putAttribute($attrib, $value, $type = null) 
194
    {
195
        if ($type == null) {
196
            $type = gettype($value);
197
        }
198

    
199
        switch ($type) {
200
        case 'integer':
201
            return radius_put_int($this->res, $attrib, $value);
202
        
203
        case 'addr':
204
            return radius_put_addr($this->res, $attrib, $value);
205
            
206
        case 'string':
207
        default:
208
            return radius_put_attr($this->res, $attrib, $value);
209
        }
210

    
211
    }
212
    
213
    /**
214
     * Puts a vendor-specific attribute.
215
     *
216
     * @access public
217
     * @param  integer $vendor       Vendor (MSoft, Cisco, ...)
218
     * @param  integer $attrib       Attribute-number
219
     * @param  mixed   $port         Attribute-value
220
     * @param  type    $type         Attribute-type
221
     * @return bool  true on success, false on error
222
     */ 
223
    function putVendorAttribute($vendor, $attrib, $value, $type = null) 
224
    {
225
        
226
        if ($type == null) {
227
            $type = gettype($value);
228
        }
229
        
230
        switch ($type) {
231
        case 'integer':
232
            return radius_put_vendor_int($this->res, $vendor, $attrib, $value);
233
        
234
        case 'addr':
235
            return radius_put_vendor_addr($this->res, $vendor,$attrib, $value);
236
            
237
        case 'string':
238
        default:
239
            return radius_put_vendor_attr($this->res, $vendor, $attrib, $value);
240
        }
241
        
242
    }    
243

    
244
    /**
245
     * Prints known attributes received from the server.
246
     *
247
     * @access public
248
     */     
249
    function dumpAttributes()
250
    {
251
        foreach ($this->attributes as $name => $data) {
252
            echo "$name:$data<br>\n";
253
        }
254
    }
255

    
256
    /**
257
     * Return our know attributes array received from the server.
258
     *
259
     * @access public
260
     */
261
    function listAttributes()
262
    {
263
        return $this->attributes;
264
    }
265

    
266
    /**
267
     * Overwrite this. 
268
     *
269
     * @access public
270
     */         
271
    function open() 
272
    {
273
    }
274

    
275
    /**
276
     * Overwrite this.
277
     *
278
     * @access public
279
     */         
280
    function createRequest()
281
    {
282
    }
283
    
284
    /**
285
     * Puts standard attributes.
286
     *
287
     * @access public
288
     */ 
289
    function putStandardAttributes()
290
    {
291
        $this->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_ETHERNET);
292
        $this->putAttribute(RADIUS_SERVICE_TYPE, RADIUS_LOGIN);
293
    }
294
    
295
    /**
296
     * Puts custom attributes.
297
     *
298
     * @access public
299
     */ 
300
    function putAuthAttributes()
301
    {
302
        if (isset($this->username)) {
303
            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
304
        }
305
    }
306
    
307
    /**
308
     * Configures the radius library.
309
     *
310
     * @access public
311
     * @param  string  $servername   Servername or IP-Address
312
     * @param  integer $port         Portnumber
313
     * @param  string  $sharedSecret Shared secret
314
     * @param  integer $timeout      Timeout for each request
315
     * @param  integer $maxtries     Max. retries for each request          
316
     * @return bool  true on success, false on error
317
     * @see addServer()
318
     */      
319
    function putServer($servername, $port = 0, $sharedsecret = 'testing123', $timeout = 3, $maxtries = 3) 
320
    {
321
        if (!radius_add_server($this->res, $servername, $port, $sharedsecret, $timeout, $maxtries)) {
322
            return false;
323
        }
324
        return true;
325
    }
326
    
327
    /**
328
     * Configures the radius library via external configurationfile
329
     *
330
     * @access public
331
     * @param  string  $servername   Servername or IP-Address
332
     * @return bool  true on success, false on error
333
     */      
334
    function putConfigfile($file) 
335
    {
336
        if (!radius_config($this->res, $file)) {
337
            return false;
338
        }
339
        return true;
340
    }    
341
        
342
    /**
343
     * Initiates a RADIUS request. 
344
     *
345
     * @access public
346
     * @return bool  true on success, false on errors     
347
     */ 
348
    function start()
349
    {
350
        if (!$this->open()) {
351
            return false;
352
        }
353
        
354
        foreach ($this->_servers as $s) {
355
	        // Servername, port, sharedsecret, timeout, retries
356
            if (!$this->putServer($s[0], $s[1], $s[2], $s[3], $s[4])) {
357
                return false;
358
            }
359
        }
360
        
361
        if (!empty($this->_configfile)) {
362
            if (!$this->putConfigfile($this->_configfile)) {
363
                return false;
364
            }
365
        }
366
        
367
        $this->createRequest();
368
	$this->putStandardAttributes();
369
        $this->putAuthAttributes();
370
        return true;
371
    }
372
    
373
    /**
374
     * Sends a prepared RADIUS request and waits for a response
375
     *
376
     * @access public
377
     * @return mixed  true on success, false on reject, PEAR_Error on error
378
     */ 
379
    function send()
380
    {
381
        $req = radius_send_request($this->res);
382
        if (!$req) {
383
            return $this->raiseError('Error sending request: ' . $this->getError());
384
        }
385

    
386
        switch($req) {
387
        case RADIUS_ACCESS_ACCEPT:
388
            if (is_subclass_of($this, 'auth_radius_acct')) {
389
                return $this->raiseError('RADIUS_ACCESS_ACCEPT is unexpected for accounting');
390
            }
391
            return true;
392

    
393
        case RADIUS_ACCESS_REJECT:
394
            return false;
395
            
396
        case RADIUS_ACCOUNTING_RESPONSE:
397
            if (is_subclass_of($this, 'auth_radius_pap')) {
398
                return $this->raiseError('RADIUS_ACCOUNTING_RESPONSE is unexpected for authentication');
399
            }
400
            return true;
401

    
402
        default:
403
            return $this->raiseError("Unexpected return value: $req");
404
        }    
405
        
406
    }
407

    
408
    /**
409
     * Reads all received attributes after sending the request.
410
     *
411
     * This methos stores know attributes in the property attributes, 
412
     * all attributes (including known attibutes) are stored in rawAttributes 
413
     * or rawVendorAttributes.
414
     * NOTE: call this functio also even if the request was rejected, because the 
415
     * Server returns usualy an errormessage
416
     *
417
     * @access public
418
     * @return bool   true on success, false on error
419
     */     
420
    function getAttributes()
421
    {
422

    
423
        while ($attrib = radius_get_attr($this->res)) {
424

    
425
            if (!is_array($attrib)) {
426
                return false;
427
            }        
428

    
429
            $attr = $attrib['attr'];
430
            $data = $attrib['data'];
431

    
432
            $this->rawAttributes[$attr] = $data;
433

    
434
            switch ($attr) {
435
            case RADIUS_FRAMED_IP_ADDRESS:
436
                $this->attributes['framed_ip'] = radius_cvt_addr($data);
437
                break;
438

    
439
            case RADIUS_FRAMED_IP_NETMASK:
440
                $this->attributes['framed_mask'] = radius_cvt_addr($data);
441
                break;
442

    
443
            case RADIUS_FRAMED_MTU:
444
                $this->attributes['framed_mtu'] = radius_cvt_int($data);
445
                break;
446

    
447
            case RADIUS_FRAMED_COMPRESSION:
448
                $this->attributes['framed_compression'] = radius_cvt_int($data);
449
                break;
450

    
451
            case RADIUS_SESSION_TIMEOUT:
452
                $this->attributes['session_timeout'] = radius_cvt_int($data);
453
                break;
454

    
455
            case RADIUS_IDLE_TIMEOUT:
456
                $this->attributes['idle_timeout'] = radius_cvt_int($data);
457
                break;
458

    
459
            case RADIUS_SERVICE_TYPE:
460
                $this->attributes['service_type'] = radius_cvt_int($data);
461
                break;
462

    
463
            case RADIUS_CLASS:
464
                $this->attributes['class'] = radius_cvt_int($data);
465
                break;
466

    
467
            case RADIUS_FRAMED_PROTOCOL:
468
                $this->attributes['framed_protocol'] = radius_cvt_int($data);
469
                break;
470

    
471
            case RADIUS_FRAMED_ROUTING:
472
                $this->attributes['framed_routing'] = radius_cvt_int($data);
473
                break;
474

    
475
            case RADIUS_FILTER_ID:
476
                $this->attributes['filter_id'] = radius_cvt_string($data);
477
                break;
478

    
479
            case RADIUS_REPLY_MESSAGE:
480
                $this->attributes['reply_message'] = radius_cvt_string($data);
481
                break;
482

    
483
            case RADIUS_VENDOR_SPECIFIC:
484
                $attribv = radius_get_vendor_attr($data);
485
                if (!is_array($attribv)) {
486
                    return false;
487
                }
488
                    
489
                $vendor = $attribv['vendor'];
490
                $attrv = $attribv['attr'];
491
                $datav = $attribv['data'];
492
                
493
                $this->rawVendorAttributes[$vendor][$attrv] = $datav;
494

    
495
                if ($vendor == RADIUS_VENDOR_MICROSOFT) {
496

    
497
                    switch ($attrv) {
498
                    case RADIUS_MICROSOFT_MS_CHAP2_SUCCESS:
499
                        $this->attributes['ms_chap2_success'] = radius_cvt_string($datav);
500
                        break;
501

    
502
                    case RADIUS_MICROSOFT_MS_CHAP_ERROR:
503
                        $this->attributes['ms_chap_error'] = radius_cvt_string(substr($datav,1));
504
                        break;
505

    
506
                    case RADIUS_MICROSOFT_MS_CHAP_DOMAIN:
507
                        $this->attributes['ms_chap_domain'] = radius_cvt_string($datav);
508
                        break;
509

    
510
                    case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
511
                        $this->attributes['ms_mppe_encryption_policy'] = radius_cvt_int($datav);
512
                        break;
513

    
514
                    case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
515
                        $this->attributes['ms_mppe_encryption_types'] = radius_cvt_int($datav);
516
                        break;
517

    
518
                    case RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS:
519
                        $demangled = radius_demangle($this->res, $datav);
520
                        $this->attributes['ms_chap_mppe_lm_key'] = substr($demangled, 0, 8);
521
                        $this->attributes['ms_chap_mppe_nt_key'] = substr($demangled, 8, RADIUS_MPPE_KEY_LEN);
522
                        break;
523

    
524
                    case RADIUS_MICROSOFT_MS_MPPE_SEND_KEY:
525
                        $this->attributes['ms_chap_mppe_send_key'] = radius_demangle_mppe_key($this->res, $datav);
526
                        break;
527

    
528
                    case RADIUS_MICROSOFT_MS_MPPE_RECV_KEY:
529
                        $this->attributes['ms_chap_mppe_recv_key'] = radius_demangle_mppe_key($this->res, $datav);
530
                        break;
531

    
532
                    case RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER:
533
                        $this->attributes['ms_primary_dns_server'] = radius_cvt_string($datav);
534
                        break;
535
                    }
536
                }
537

    
538
                if ($vendor == RADIUS_VENDOR_BAY) {
539

    
540
                    switch ($attrv) {
541
                    case RADIUS_BAY_CES_GROUP:
542
                        $this->attributes['ces_group'] = radius_cvt_string($datav);
543
                        break;
544
                    }
545
                }
546

    
547
                if ($vendor == 3309) {	/* RADIUS_VENDOR_NOMADIX */
548

    
549
                    switch ($attrv) {
550
                    case 1: /* RADIUS_NOMADIX_BW_UP */
551
                        $this->attributes['bw_up'] = radius_cvt_int($datav);
552
                        break;
553
                    case 2: /* RADIUS_NOMADIX_BW_DOWN */
554
                        $this->attributes['bw_down'] = radius_cvt_int($datav);
555
                        break;
556
                    case 3: /* RADIUS_NOMADIX_URL_REDIRECTION */
557
                        $this->attributes['url_redirection'] = radius_cvt_string($datav);
558
                        break;
559
                    case 5: /* RADIUS_NOMADIX_EXPIRATION */
560
                        $this->attributes['expiration'] = radius_cvt_string($datav);
561
                        break;
562
                    case 7: /* RADIUS_NOMADIX_MAXBYTESUP */
563
                        $this->attributes['maxbytesup'] = radius_cvt_int($datav);
564
                        break;
565
                    case 8: /* RADIUS_NOMADIX_MAXBYTESDOWN */
566
                        $this->attributes['maxbytesdown'] = radius_cvt_int($datav);
567
                        break;
568
                    case 10: /* RADIUS_NOMADIX_LOGOFF_URL */
569
                        $this->attributes['url_logoff'] = radius_cvt_string($datav);
570
                        break;
571
                    }
572
                } 
573

    
574
		if ($vendor == 14122) { /* RADIUS_VENDOR_WISPr Wi-Fi Alliance */
575

    
576
		    switch ($attrv) {
577
		    case 1: /* WISPr-Location-ID */
578
			$this->attributes['location_id'] = radius_cvt_string($datav);
579
			break;
580
		    case 2: /* WISPr-Location-Name */
581
			$this->attributes['location_name'] = radius_cvt_string($datav);
582
			break;
583
		    case 3: /* WISPr-Logoff-URL */
584
			$this->attributes['url_logoff'] = radius_cvt_string($datav);
585
			break;
586
		    case 4: /* WISPr-Redirection-URL */
587
			$this->attributes['url_redirection'] = radius_cvt_string($datav);
588
			break;
589
		    case 5: /* WISPr-Bandwidth-Min-Up */
590
			$this->attributes['bw_minbytesup'] = radius_cvt_int($datav);
591
			break;
592
		    case 6: /* WISPr-Bandwidth-Min-Down */
593
			$this->attributes['bw_minbytesdown'] = radius_cvt_int($datav);
594
			break;
595
		    case 7: /* WIPSr-Bandwidth-Max-Up */
596
			$this->attributes['bw_maxbytesup'] = radius_cvt_int($datav);
597
			break;
598
		    case 8: /* WISPr-Bandwidth-Max-Down */
599
			$this->attributes['bw_maxbytesdown'] = radius_cvt_int($datav);
600
			break;
601
		    case 9: /* WISPr-Session-Terminate-Time */
602
			$this->attributes['session_terminate_time'] = radius_cvt_string($datav);
603
			break;
604
		    case 10: /* WISPr-Session-Terminate-End-Of-Day */
605
			$this->attributes['session_terminate_endofday'] = radius_cvt_int($datav);
606
			break;
607
		    case 11: /* WISPr-Billing-Class-Of-Service */
608
			$this->attributes['billing_class_of_service'] = radius_cvt_string($datav);
609
			break;
610
		   }
611
		}
612

    
613
                break;
614
                
615
            }
616
        }    
617

    
618
        return true;
619
    }
620
    
621
    /**
622
     * Frees resources.
623
     *
624
     * Calling this method is always a good idea, because all security relevant
625
     * attributes are filled with Nullbytes to leave nothing in the mem.
626
     *
627
     * @access public
628
     */   
629
    function close()
630
    {
631
        if ($this->res != null) {
632
            radius_close($this->res);
633
            $this->res = null;
634
        }
635
        $this->username = str_repeat("\0", strlen($this->username));
636
        $this->password = str_repeat("\0", strlen($this->password));
637
    }
638
    
639
}
640

    
641
/**
642
 * class Auth_RADIUS_PAP
643
 *
644
 * Class for authenticating using PAP (Plaintext)
645
 * 
646
 * @package Auth_RADIUS 
647
 */
648
class Auth_RADIUS_PAP extends Auth_RADIUS 
649
{
650

    
651
    /**
652
     * Constructor
653
     *
654
     * @param  string  $username   Username
655
     * @param  string  $password   Password
656
     * @return void
657
     */
658
    function Auth_RADIUS_PAP($username = null, $password = null)
659
    {
660
        $this->Auth_RADIUS();
661
        $this->username = $username;
662
        $this->password = $password;
663
    }
664
    
665
    /**
666
     * Creates a RADIUS resource
667
     *
668
     * Creates a RADIUS resource for authentication. This should be the first
669
     * call before you make any other things with the library.
670
     *
671
     * @return bool   true on success, false on error
672
     */
673
    function open() 
674
    {
675
        $this->res = radius_auth_open();
676
        if (!$this->res) {
677
            return false;
678
        }
679
        return true;
680
    }
681
    
682
    /**
683
     * Creates an authentication request 
684
     *
685
     * Creates an authentication request.
686
     * You MUST call this method before you can put any attribute
687
     *
688
     * @return bool   true on success, false on error
689
     */
690
    function createRequest()
691
    {
692
        if (!radius_create_request($this->res, RADIUS_ACCESS_REQUEST)) {
693
            return false;
694
        }
695
        return true;
696
    }
697

    
698
    /**
699
     * Put authentication specific attributes 
700
     *
701
     * @return void
702
     */
703
    function putAuthAttributes()
704
    {
705
        if (isset($this->username)) {
706
            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
707
        }
708
        if (isset($this->password)) {
709
            $this->putAttribute(RADIUS_USER_PASSWORD, $this->password);
710
        }
711
    }
712

    
713
}
714

    
715
/**
716
 * class Auth_RADIUS_CHAP_MD5
717
 *
718
 * Class for authenticating using CHAP-MD5 see RFC1994.
719
 * Instead og the plaintext password the challenge and 
720
 * the response are needed.
721
 * 
722
 * @package Auth_RADIUS 
723
 */
724
class Auth_RADIUS_CHAP_MD5 extends Auth_RADIUS_PAP
725
{
726
    /**
727
     * 8 Bytes binary challenge
728
     * @var  string
729
     */
730
    var $challenge = null;
731

    
732
    /**
733
     * 16 Bytes MD5 response binary
734
     * @var  string
735
     */
736
    var $response = null;
737
    
738
    /**
739
     * Id of the authentication request. Should incremented after every request.
740
     * @var  integer
741
     */
742
    var $chapid = 1;
743
    
744
    /**
745
     * Constructor
746
     *
747
     * @param  string  $username   Username
748
     * @param  string  $challenge  8 Bytes Challenge (binary)
749
     * @param  integer $chapid     Requestnumber
750
     * @return void
751
     */
752
    function Auth_RADIUS_CHAP_MD5($username = null, $challenge = null, $chapid = 1)
753
    {
754
        $this->Auth_RADIUS_PAP();
755
        $this->username = $username;
756
        $this->challenge = $challenge;
757
        $this->chapid = $chapid;
758
    }
759
    
760
    /**
761
     * Put CHAP-MD5 specific attributes
762
     *
763
     * For authenticating using CHAP-MD5 via RADIUS you have to put the challenge 
764
     * and the response. The chapid is inserted in the first byte of the response.
765
     *
766
     * @return void
767
     */
768
    function putAuthAttributes()
769
    {
770
        if (isset($this->username)) {
771
            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
772
        }
773
        if (isset($this->response)) {
774
            $response = pack('C', $this->chapid) . $this->response;
775
            $this->putAttribute(RADIUS_CHAP_PASSWORD, $response);
776
        }
777
        if (isset($this->challenge)) {
778
            $this->putAttribute(RADIUS_CHAP_CHALLENGE, $this->challenge);
779
        }
780
    }
781
    
782
    /**
783
     * Frees resources.
784
     *
785
     * Calling this method is always a good idea, because all security relevant
786
     * attributes are filled with Nullbytes to leave nothing in the mem.
787
     *
788
     * @access public
789
     */   
790
    function close()
791
    {
792
        Auth_RADIUS_PAP::close();
793
        $this->challenge =  str_repeat("\0", strlen($this->challenge));
794
        $this->response =  str_repeat("\0", strlen($this->response));
795
    }    
796
    
797
}
798

    
799
/**
800
 * class Auth_RADIUS_MSCHAPv1
801
 *
802
 * Class for authenticating using MS-CHAPv1 see RFC2433
803
 * 
804
 * @package Auth_RADIUS 
805
 */
806
class Auth_RADIUS_MSCHAPv1 extends Auth_RADIUS_CHAP_MD5 
807
{
808
    /**
809
     * LAN-Manager-Response
810
     * @var  string
811
     */
812
    var $lmResponse = null;
813

    
814
    /**
815
     * Wether using deprecated LM-Responses or not.
816
     * 0 = use LM-Response, 1 = use NT-Response
817
     * @var  bool
818
     */
819
    var $flags = 1;
820
    
821
    /**
822
     * Put MS-CHAPv1 specific attributes 
823
     *
824
     * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge 
825
     * and the response. The response has this structure:
826
     * struct rad_mschapvalue {
827
     *   u_char ident;
828
     *   u_char flags;
829
     *   u_char lm_response[24];
830
     *   u_char response[24];
831
     * };
832
     * 
833
     * @return void
834
     */
835
    function putAuthAttributes()
836
    {
837
        if (isset($this->username)) {
838
            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
839
        }
840
        if (isset($this->response) || isset($this->lmResponse)) {
841
            $lmResp = isset($this->lmResponse) ? $this->lmResponse : str_repeat ("\0", 24);
842
            $ntResp = isset($this->response)   ? $this->response :   str_repeat ("\0", 24);
843
            $resp = pack('CC', $this->chapid, $this->flags) . $lmResp . $ntResp;
844
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_RESPONSE, $resp);
845
        }
846
        if (isset($this->challenge)) {        
847
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
848
        }
849
    }    
850
}
851

    
852
/**
853
 * class Auth_RADIUS_MSCHAPv2
854
 *
855
 * Class for authenticating using MS-CHAPv2 see RFC2759
856
 * 
857
 * @package Auth_RADIUS 
858
 */
859
class Auth_RADIUS_MSCHAPv2 extends Auth_RADIUS_MSCHAPv1 
860
{
861
    /**
862
     * 16 Bytes binary challenge
863
     * @var  string
864
     */
865
    var $challenge = null;
866
    
867
    /**
868
     * 16 Bytes binary Peer Challenge
869
     * @var  string
870
     */
871
    var $peerChallenge = null;
872

    
873
  /**
874
     * Put MS-CHAPv2 specific attributes 
875
     *
876
     * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge 
877
     * and the response. The response has this structure:
878
     * struct rad_mschapv2value {
879
     *   u_char ident;
880
     *   u_char flags;
881
     *   u_char pchallenge[16];
882
     *   u_char reserved[8];
883
     *   u_char response[24];
884
     * };
885
     * where pchallenge is the peer challenge. Like for MS-CHAPv1 we set the flags field to 1.
886
     * @return void
887
     */    
888
    function putAuthAttributes()
889
    {
890
        if (isset($this->username)) {
891
            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
892
        }
893
        if (isset($this->response) && isset($this->peerChallenge)) {
894
            // Response: chapid, flags (1 = use NT Response), Peer challenge, reserved, Response        
895
            $resp = pack('CCa16a8a24',$this->chapid , 1, $this->peerChallenge, str_repeat("\0", 8), $this->response);        
896
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP2_RESPONSE, $resp);
897
        }
898
        if (isset($this->challenge)) {
899
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
900
        }
901
    }    
902
    
903
    /**
904
     * Frees resources.
905
     *
906
     * Calling this method is always a good idea, because all security relevant
907
     * attributes are filled with Nullbytes to leave nothing in the mem.
908
     *
909
     * @access public
910
     */   
911
    function close()
912
    {
913
        Auth_RADIUS_MSCHAPv1::close();
914
        $this->peerChallenge = str_repeat("\0", strlen($this->peerChallenge));
915
    }       
916
}
917

    
918
/**
919
 * class Auth_RADIUS_Acct
920
 *
921
 * Class for RADIUS accounting
922
 * 
923
 * @package Auth_RADIUS 
924
 */
925
class Auth_RADIUS_Acct extends Auth_RADIUS 
926
{
927
    /**
928
     * Defines where the Authentication was made, possible values are:
929
     * RADIUS_AUTH_RADIUS, RADIUS_AUTH_LOCAL, RADIUS_AUTH_REMOTE
930
     * @var  integer
931
     */
932
    var $authentic = null;
933

    
934
   /**
935
     * Defines the type of the accounting request, on of:
936
     * RADIUS_START, RADIUS_STOP, RADIUS_ACCOUNTING_ON, RADIUS_ACCOUNTING_OFF
937
     * @var  integer
938
     */    
939
    var $status_type = null;
940

    
941
   /**
942
     * The time the user was logged in in seconds
943
     * @var  integer
944
     */    
945
    var $session_time = null;
946

    
947
   /**
948
     * A uniq identifier for the session of the user, maybe the PHP-Session-Id
949
     * @var  string
950
     */    
951
    var $session_id = null;
952
    
953
    /**
954
     * Constructor
955
     *
956
     * This function is disabled for M0n0wall since we use our own session_id
957
     *
958
     * Generates a predefined session_id. We use the Remote-Address, the PID, and the Current user.
959
     * @return void
960
     *
961
    function Auth_RADIUS_Acct()
962
    {
963
        $this->Auth_RADIUS();
964
        
965
        if (isset($_SERVER)) {
966
            $var = &$_SERVER;
967
        } else {
968
            $var = &$GLOBALS['HTTP_SERVER_VARS'];
969
        }
970

    
971
        $this->session_id = sprintf("%s:%d-%s", isset($var['REMOTE_ADDR']) ? $var['REMOTE_ADDR'] : '127.0.0.1' , getmypid(), get_current_user());
972
    }
973
    */
974

    
975
    /**
976
     * Constructor
977
     *
978
     */
979

    
980
    function Auth_RADIUS_Acct()
981
    {
982
        $this->Auth_RADIUS();
983
    }
984

    
985
    /**
986
     * Creates a RADIUS resource
987
     *
988
     * Creates a RADIUS resource for accounting. This should be the first
989
     * call before you make any other things with the library.
990
     *
991
     * @return bool   true on success, false on error
992
     */
993
    function open() 
994
    {
995
        $this->res = radius_acct_open();
996
        if (!$this->res) {
997
            return false;
998
        }
999
        return true;
1000
    }
1001

    
1002
   /**
1003
     * Creates an accounting request 
1004
     *
1005
     * Creates an accounting request.
1006
     * You MUST call this method before you can put any attribute.
1007
     *
1008
     * @return bool   true on success, false on error
1009
     */
1010
    function createRequest()
1011
    {
1012
        if (!radius_create_request($this->res, RADIUS_ACCOUNTING_REQUEST)) {
1013
            return false;
1014
        }
1015
        return true;
1016
    }   
1017
   
1018
  /**
1019
     * Put attributes for accounting.
1020
     *
1021
     * Here we put some accounting values. There many more attributes for accounting, 
1022
     * but for web-applications only certain attributes make sense.
1023
     * @return void
1024
     */ 
1025
    function putAuthAttributes()
1026
    {
1027
        $this->putAttribute(RADIUS_ACCT_SESSION_ID, $this->session_id);
1028
        $this->putAttribute(RADIUS_ACCT_STATUS_TYPE, $this->status_type);
1029
        if (isset($this->session_time) && $this->status_type == RADIUS_STOP) {
1030
            $this->putAttribute(RADIUS_ACCT_SESSION_TIME, $this->session_time);
1031
        }
1032
        if (isset($this->authentic)) {
1033
            $this->putAttribute(RADIUS_ACCT_AUTHENTIC, $this->authentic);
1034
        }
1035
        
1036
    }    
1037
    
1038
}
1039

    
1040
/**
1041
 * class Auth_RADIUS_Acct_Start
1042
 *
1043
 * Class for RADIUS accounting. Its usualy used, after the user has logged in.
1044
 * 
1045
 * @package Auth_RADIUS
1046
 */
1047
class Auth_RADIUS_Acct_Start extends Auth_RADIUS_Acct 
1048
{
1049
   /**
1050
     * Defines the type of the accounting request.
1051
     * It is set to RADIUS_START by default in this class.
1052
     * @var  integer
1053
     */    
1054
    var $status_type = RADIUS_START;
1055
}
1056

    
1057
/**
1058
 * class Auth_RADIUS_Acct_Start
1059
 *
1060
 * Class for RADIUS accounting. Its usualy used, after the user has logged out.
1061
 *
1062
 * @package Auth_RADIUS
1063
 */
1064
class Auth_RADIUS_Acct_Stop extends Auth_RADIUS_Acct
1065
{
1066
   /**
1067
     * Defines the type of the accounting request.
1068
     * It is set to RADIUS_STOP by default in this class.
1069
     * @var  integer
1070
     */
1071
    var $status_type = RADIUS_STOP;
1072
}
1073

    
1074
if (!defined('RADIUS_UPDATE'))
1075
    define('RADIUS_UPDATE', 3);
1076

    
1077
/**
1078
 * class Auth_RADIUS_Acct_Update
1079
 *
1080
 * Class for interim RADIUS accounting updates.
1081
 *
1082
 * @package Auth_RADIUS
1083
 */
1084
class Auth_RADIUS_Acct_Update extends Auth_RADIUS_Acct
1085
{
1086
   /**
1087
     * Defines the type of the accounting request.
1088
     * It is set to RADIUS_UPDATE by default in this class.
1089
     * @var  integer
1090
     */
1091
    var $status_type = RADIUS_UPDATE;
1092
}
1093

    
1094
?>
(16-16/27)