Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1173 jp_milcent 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: RADIUS.php,v 1.1 2006-12-14 15:04:28 jp_milcent Exp $
34
*/
35
 
36
require_once 'PEAR.php';
37
 
38
/**
39
* Client implementation of RADIUS. This are wrapper classes for
40
* the RADIUS PECL.
41
* Provides RADIUS Authentication (RFC2865) and RADIUS Accounting (RFC2866).
42
*
43
* @package Auth_RADIUS
44
* @author  Michael Bretterklieber <michael@bretterklieber.com>
45
* @access  public
46
* @version $Revision: 1.1 $
47
*/
48
 
49
/**
50
 * class Auth_RADIUS
51
 *
52
 * Abstract base class for RADIUS
53
 *
54
 * @package Auth_RADIUS
55
 */
56
class Auth_RADIUS extends PEAR {
57
 
58
    /**
59
     * List of RADIUS servers.
60
     * @var  array
61
     * @see  addServer(), putServer()
62
     */
63
    var $_servers  = array();
64
 
65
    /**
66
     * Path to the configuration-file.
67
     * @var  string
68
     * @see  setConfigFile()
69
     */
70
    var $_configfile = null;
71
 
72
    /**
73
     * Resource.
74
     * @var  resource
75
     * @see  open(), close()
76
     */
77
    var $res = null;
78
 
79
    /**
80
     * Username for authentication and accounting requests.
81
     * @var  string
82
     */
83
    var $username = null;
84
 
85
    /**
86
     * Password for plaintext-authentication (PAP).
87
     * @var  string
88
     */
89
    var $password = null;
90
 
91
    /**
92
     * List of known attributes.
93
     * @var  array
94
     * @see  dumpAttributes(), getAttributes()
95
     */
96
    var $attributes = array();
97
 
98
    /**
99
     * List of raw attributes.
100
     * @var  array
101
     * @see  dumpAttributes(), getAttributes()
102
     */
103
    var $rawAttributes = array();
104
 
105
    /**
106
     * List of raw vendor specific attributes.
107
     * @var  array
108
     * @see  dumpAttributes(), getAttributes()
109
     */
110
    var $rawVendorAttributes = array();
111
 
112
    /**
113
     * Constructor
114
     *
115
     * Loads the RADIUS PECL/extension
116
     *
117
     * @return void
118
     */
119
    function Auth_RADIUS()
120
    {
121
        $this->PEAR();
122
        $this->loadExtension('radius');
123
    }
124
 
125
    /**
126
     * Adds a RADIUS server to the list of servers for requests.
127
     *
128
     * At most 10 servers may be specified.	When multiple servers
129
     * are given, they are tried in round-robin fashion until a
130
     * valid response is received
131
     *
132
     * @access public
133
     * @param  string  $servername   Servername or IP-Address
134
     * @param  integer $port         Portnumber
135
     * @param  string  $sharedSecret Shared secret
136
     * @param  integer $timeout      Timeout for each request
137
     * @param  integer $maxtries     Max. retries for each request
138
     * @return void
139
     */
140
    function addServer($servername = 'localhost', $port = 0, $sharedSecret = 'testing123', $timeout = 3, $maxtries = 3)
141
    {
142
        $this->_servers[] = array($servername, $port, $sharedSecret, $timeout, $maxtries);
143
    }
144
 
145
    /**
146
     * Returns an error message, if an error occurred.
147
     *
148
     * @access public
149
     * @return string
150
     */
151
    function getError()
152
    {
153
        return radius_strerror($this->res);
154
    }
155
 
156
    /**
157
     * Sets the configuration-file.
158
     *
159
     * @access public
160
     * @param  string  $file Path to the configuration file
161
     * @return void
162
     */
163
    function setConfigfile($file)
164
    {
165
        $this->_configfile = $file;
166
    }
167
 
168
    /**
169
     * Puts an attribute.
170
     *
171
     * @access public
172
     * @param  integer $attrib       Attribute-number
173
     * @param  mixed   $port         Attribute-value
174
     * @param  type    $type         Attribute-type
175
     * @return bool  true on success, false on error
176
     */
177
    function putAttribute($attrib, $value, $type = null)
178
    {
179
        if ($type == null) {
180
            $type = gettype($value);
181
        }
182
 
183
        switch ($type) {
184
        case 'integer':
185
            return radius_put_int($this->res, $attrib, $value);
186
 
187
        case 'addr':
188
            return radius_put_addr($this->res, $attrib, $value);
189
 
190
        case 'string':
191
        default:
192
            return radius_put_attr($this->res, $attrib, $value);
193
        }
194
 
195
    }
196
 
197
    /**
198
     * Puts a vendor-specific attribute.
199
     *
200
     * @access public
201
     * @param  integer $vendor       Vendor (MSoft, Cisco, ...)
202
     * @param  integer $attrib       Attribute-number
203
     * @param  mixed   $port         Attribute-value
204
     * @param  type    $type         Attribute-type
205
     * @return bool  true on success, false on error
206
     */
207
    function putVendorAttribute($vendor, $attrib, $value, $type = null)
208
    {
209
 
210
        if ($type == null) {
211
            $type = gettype($value);
212
        }
213
 
214
        switch ($type) {
215
        case 'integer':
216
            return radius_put_vendor_int($this->res, $vendor, $attrib, $value);
217
 
218
        case 'addr':
219
            return radius_put_vendor_addr($this->res, $vendor,$attrib, $value);
220
 
221
        case 'string':
222
        default:
223
            return radius_put_vendor_attr($this->res, $vendor, $attrib, $value);
224
        }
225
 
226
    }
227
 
228
    /**
229
     * Prints known attributes received from the server.
230
     *
231
     * @access public
232
     */
233
    function dumpAttributes()
234
    {
235
        foreach ($this->attributes as $name => $data) {
236
            echo "$name:$data<br>\n";
237
        }
238
    }
239
 
240
    /**
241
     * Overwrite this.
242
     *
243
     * @access public
244
     */
245
    function open()
246
    {
247
    }
248
 
249
    /**
250
     * Overwrite this.
251
     *
252
     * @access public
253
     */
254
    function createRequest()
255
    {
256
    }
257
 
258
    /**
259
     * Puts standard attributes.
260
     *
261
     * @access public
262
     */
263
    function putStandardAttributes()
264
    {
265
        if (isset($_SERVER)) {
266
            $var = &$_SERVER;
267
        } else {
268
            $var = &$GLOBALS['HTTP_SERVER_VARS'];
269
        }
270
 
271
        $this->putAttribute(RADIUS_NAS_IDENTIFIER, isset($var['HTTP_HOST']) ? $var['HTTP_HOST'] : 'localhost');
272
        $this->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_VIRTUAL);
273
        $this->putAttribute(RADIUS_SERVICE_TYPE, RADIUS_FRAMED);
274
        $this->putAttribute(RADIUS_FRAMED_PROTOCOL, RADIUS_PPP);
275
        $this->putAttribute(RADIUS_CALLING_STATION_ID, isset($var['REMOTE_HOST']) ? $var['REMOTE_HOST'] : '127.0.0.1');
276
    }
277
 
278
    /**
279
     * Puts custom attributes.
280
     *
281
     * @access public
282
     */
283
    function putAuthAttributes()
284
    {
285
        if (isset($this->username)) {
286
            $this->putAttribute(RADIUS_USER_NAME, $this->username);
287
        }
288
    }
289
 
290
    /**
291
     * Configures the radius library.
292
     *
293
     * @access public
294
     * @param  string  $servername   Servername or IP-Address
295
     * @param  integer $port         Portnumber
296
     * @param  string  $sharedSecret Shared secret
297
     * @param  integer $timeout      Timeout for each request
298
     * @param  integer $maxtries     Max. retries for each request
299
     * @return bool  true on success, false on error
300
     * @see addServer()
301
     */
302
    function putServer($servername, $port = 0, $sharedsecret = 'testing123', $timeout = 3, $maxtries = 3)
303
    {
304
        if (!radius_add_server($this->res, $servername, $port, $sharedsecret, $timeout, $maxtries)) {
305
            return false;
306
        }
307
        return true;
308
    }
309
 
310
    /**
311
     * Configures the radius library via external configurationfile
312
     *
313
     * @access public
314
     * @param  string  $servername   Servername or IP-Address
315
     * @return bool  true on success, false on error
316
     */
317
    function putConfigfile($file)
318
    {
319
        if (!radius_config($this->res, $file)) {
320
            return false;
321
        }
322
        return true;
323
    }
324
 
325
    /**
326
     * Initiates a RADIUS request.
327
     *
328
     * @access public
329
     * @return bool  true on success, false on errors
330
     */
331
    function start()
332
    {
333
        if (!$this->open()) {
334
            return false;
335
        }
336
 
337
        foreach ($this->_servers as $s) {
338
	        // Servername, port, sharedsecret, timeout, retries
339
            if (!$this->putServer($s[0], $s[1], $s[2], $s[3], $s[4])) {
340
                return false;
341
            }
342
        }
343
 
344
        if (!empty($this->_configfile)) {
345
            if (!$this->putConfigfile($this->_configfile)) {
346
                return false;
347
            }
348
        }
349
 
350
        $this->createRequest();
351
        $this->putStandardAttributes();
352
        $this->putAuthAttributes();
353
        return true;
354
    }
355
 
356
    /**
357
     * Sends a prepared RADIUS request and waits for a response
358
     *
359
     * @access public
360
     * @return mixed  true on success, false on reject, PEAR_Error on error
361
     */
362
    function send()
363
    {
364
        $req = radius_send_request($this->res);
365
        if (!$req) {
366
            return $this->raiseError('Error sending request: ' . $this->getError());
367
        }
368
 
369
        switch($req) {
370
        case RADIUS_ACCESS_ACCEPT:
371
            if (is_subclass_of($this, 'auth_radius_acct')) {
372
                return $this->raiseError('RADIUS_ACCESS_ACCEPT is unexpected for accounting');
373
            }
374
            return true;
375
 
376
        case RADIUS_ACCESS_REJECT:
377
            return false;
378
 
379
        case RADIUS_ACCOUNTING_RESPONSE:
380
            if (is_subclass_of($this, 'auth_radius_pap')) {
381
                return $this->raiseError('RADIUS_ACCOUNTING_RESPONSE is unexpected for authentication');
382
            }
383
            return true;
384
 
385
        default:
386
            return $this->raiseError("Unexpected return value: $req");
387
        }
388
 
389
    }
390
 
391
    /**
392
     * Reads all received attributes after sending the request.
393
     *
394
     * This methos stores know attributes in the property attributes,
395
     * all attributes (including known attibutes) are stored in rawAttributes
396
     * or rawVendorAttributes.
397
     * NOTE: call this functio also even if the request was rejected, because the
398
     * Server returns usualy an errormessage
399
     *
400
     * @access public
401
     * @return bool   true on success, false on error
402
     */
403
    function getAttributes()
404
    {
405
 
406
        while ($attrib = radius_get_attr($this->res)) {
407
 
408
            if (!is_array($attrib)) {
409
                return false;
410
            }
411
 
412
            $attr = $attrib['attr'];
413
            $data = $attrib['data'];
414
 
415
            $this->rawAttributes[$attr] = $data;
416
 
417
            switch ($attr) {
418
            case RADIUS_FRAMED_IP_ADDRESS:
419
                $this->attributes['framed_ip'] = radius_cvt_addr($data);
420
                break;
421
 
422
            case RADIUS_FRAMED_IP_NETMASK:
423
                $this->attributes['framed_mask'] = radius_cvt_addr($data);
424
                break;
425
 
426
            case RADIUS_FRAMED_MTU:
427
                $this->attributes['framed_mtu'] = radius_cvt_int($data);
428
                break;
429
 
430
            case RADIUS_FRAMED_COMPRESSION:
431
                $this->attributes['framed_compression'] = radius_cvt_int($data);
432
                break;
433
 
434
            case RADIUS_SESSION_TIMEOUT:
435
                $this->attributes['session_timeout'] = radius_cvt_int($data);
436
                break;
437
 
438
            case RADIUS_IDLE_TIMEOUT:
439
                $this->attributes['idle_timeout'] = radius_cvt_int($data);
440
                break;
441
 
442
            case RADIUS_SERVICE_TYPE:
443
                $this->attributes['service_type'] = radius_cvt_int($data);
444
                break;
445
 
446
            case RADIUS_CLASS:
447
                $this->attributes['class'] = radius_cvt_int($data);
448
                break;
449
 
450
            case RADIUS_FRAMED_PROTOCOL:
451
                $this->attributes['framed_protocol'] = radius_cvt_int($data);
452
                break;
453
 
454
            case RADIUS_FRAMED_ROUTING:
455
                $this->attributes['framed_routing'] = radius_cvt_int($data);
456
                break;
457
 
458
            case RADIUS_FILTER_ID:
459
                $this->attributes['filter_id'] = radius_cvt_string($data);
460
                break;
461
 
462
            case RADIUS_VENDOR_SPECIFIC:
463
                $attribv = radius_get_vendor_attr($data);
464
                if (!is_array($attribv)) {
465
                    return false;
466
                }
467
 
468
                $vendor = $attribv['vendor'];
469
                $attrv = $attribv['attr'];
470
                $datav = $attribv['data'];
471
 
472
                $this->rawVendorAttributes[$vendor][$attrv] = $datav;
473
 
474
                if ($vendor == RADIUS_VENDOR_MICROSOFT) {
475
 
476
                    switch ($attrv) {
477
                    case RADIUS_MICROSOFT_MS_CHAP2_SUCCESS:
478
                        $this->attributes['ms_chap2_success'] = radius_cvt_string($datav);
479
                        break;
480
 
481
                    case RADIUS_MICROSOFT_MS_CHAP_ERROR:
482
                        $this->attributes['ms_chap_error'] = radius_cvt_string(substr($datav,1));
483
                        break;
484
 
485
                    case RADIUS_MICROSOFT_MS_CHAP_DOMAIN:
486
                        $this->attributes['ms_chap_domain'] = radius_cvt_string($datav);
487
                        break;
488
 
489
                    case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
490
                        $this->attributes['ms_mppe_encryption_policy'] = radius_cvt_int($datav);
491
                        break;
492
 
493
                    case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
494
                        $this->attributes['ms_mppe_encryption_types'] = radius_cvt_int($datav);
495
                        break;
496
 
497
                    case RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS:
498
                        $demangled = radius_demangle($this->res, $datav);
499
                        $this->attributes['ms_chap_mppe_lm_key'] = substr($demangled, 0, 8);
500
                        $this->attributes['ms_chap_mppe_nt_key'] = substr($demangled, 8, RADIUS_MPPE_KEY_LEN);
501
                        break;
502
 
503
                    case RADIUS_MICROSOFT_MS_MPPE_SEND_KEY:
504
                        $this->attributes['ms_chap_mppe_send_key'] = radius_demangle_mppe_key($this->res, $datav);
505
                        break;
506
 
507
                    case RADIUS_MICROSOFT_MS_MPPE_RECV_KEY:
508
                        $this->attributes['ms_chap_mppe_recv_key'] = radius_demangle_mppe_key($this->res, $datav);
509
                        break;
510
 
511
                    case RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER:
512
                        $this->attributes['ms_primary_dns_server'] = radius_cvt_string($datav);
513
                        break;
514
                    }
515
                }
516
                break;
517
 
518
            }
519
        }
520
 
521
        return true;
522
    }
523
 
524
    /**
525
     * Frees resources.
526
     *
527
     * Calling this method is always a good idea, because all security relevant
528
     * attributes are filled with Nullbytes to leave nothing in the mem.
529
     *
530
     * @access public
531
     */
532
    function close()
533
    {
534
        if ($this->res != null) {
535
            radius_close($this->res);
536
            $this->res = null;
537
        }
538
        $this->username = str_repeat("\0", strlen($this->username));
539
        $this->password = str_repeat("\0", strlen($this->password));
540
    }
541
 
542
}
543
 
544
/**
545
 * class Auth_RADIUS_PAP
546
 *
547
 * Class for authenticating using PAP (Plaintext)
548
 *
549
 * @package Auth_RADIUS
550
 */
551
class Auth_RADIUS_PAP extends Auth_RADIUS
552
{
553
 
554
    /**
555
     * Constructor
556
     *
557
     * @param  string  $username   Username
558
     * @param  string  $password   Password
559
     * @return void
560
     */
561
    function Auth_RADIUS_PAP($username = null, $password = null)
562
    {
563
        $this->Auth_RADIUS();
564
        $this->username = $username;
565
        $this->password = $password;
566
    }
567
 
568
    /**
569
     * Creates a RADIUS resource
570
     *
571
     * Creates a RADIUS resource for authentication. This should be the first
572
     * call before you make any other things with the library.
573
     *
574
     * @return bool   true on success, false on error
575
     */
576
    function open()
577
    {
578
        $this->res = radius_auth_open();
579
        if (!$this->res) {
580
            return false;
581
        }
582
        return true;
583
    }
584
 
585
    /**
586
     * Creates an authentication request
587
     *
588
     * Creates an authentication request.
589
     * You MUST call this method before you can put any attribute
590
     *
591
     * @return bool   true on success, false on error
592
     */
593
    function createRequest()
594
    {
595
        if (!radius_create_request($this->res, RADIUS_ACCESS_REQUEST)) {
596
            return false;
597
        }
598
        return true;
599
    }
600
 
601
    /**
602
     * Put authentication specific attributes
603
     *
604
     * @return void
605
     */
606
    function putAuthAttributes()
607
    {
608
        if (isset($this->username)) {
609
            $this->putAttribute(RADIUS_USER_NAME, $this->username);
610
        }
611
        if (isset($this->password)) {
612
            $this->putAttribute(RADIUS_USER_PASSWORD, $this->password);
613
        }
614
    }
615
 
616
}
617
 
618
/**
619
 * class Auth_RADIUS_CHAP_MD5
620
 *
621
 * Class for authenticating using CHAP-MD5 see RFC1994.
622
 * Instead og the plaintext password the challenge and
623
 * the response are needed.
624
 *
625
 * @package Auth_RADIUS
626
 */
627
class Auth_RADIUS_CHAP_MD5 extends Auth_RADIUS_PAP
628
{
629
    /**
630
     * 8 Bytes binary challenge
631
     * @var  string
632
     */
633
    var $challenge = null;
634
 
635
    /**
636
     * 16 Bytes MD5 response binary
637
     * @var  string
638
     */
639
    var $response = null;
640
 
641
    /**
642
     * Id of the authentication request. Should incremented after every request.
643
     * @var  integer
644
     */
645
    var $chapid = 1;
646
 
647
    /**
648
     * Constructor
649
     *
650
     * @param  string  $username   Username
651
     * @param  string  $challenge  8 Bytes Challenge (binary)
652
     * @param  integer $chapid     Requestnumber
653
     * @return void
654
     */
655
    function Auth_RADIUS_CHAP_MD5($username = null, $challenge = null, $chapid = 1)
656
    {
657
        $this->Auth_RADIUS_PAP();
658
        $this->username = $username;
659
        $this->challenge = $challenge;
660
        $this->chapid = $chapid;
661
    }
662
 
663
    /**
664
     * Put CHAP-MD5 specific attributes
665
     *
666
     * For authenticating using CHAP-MD5 via RADIUS you have to put the challenge
667
     * and the response. The chapid is inserted in the first byte of the response.
668
     *
669
     * @return void
670
     */
671
    function putAuthAttributes()
672
    {
673
        if (isset($this->username)) {
674
            $this->putAttribute(RADIUS_USER_NAME, $this->username);
675
        }
676
        if (isset($this->response)) {
677
            $response = pack('C', $this->chapid) . $this->response;
678
            $this->putAttribute(RADIUS_CHAP_PASSWORD, $response);
679
        }
680
        if (isset($this->challenge)) {
681
            $this->putAttribute(RADIUS_CHAP_CHALLENGE, $this->challenge);
682
        }
683
    }
684
 
685
    /**
686
     * Frees resources.
687
     *
688
     * Calling this method is always a good idea, because all security relevant
689
     * attributes are filled with Nullbytes to leave nothing in the mem.
690
     *
691
     * @access public
692
     */
693
    function close()
694
    {
695
        Auth_RADIUS_PAP::close();
696
        $this->challenge =  str_repeat("\0", strlen($this->challenge));
697
        $this->response =  str_repeat("\0", strlen($this->response));
698
    }
699
 
700
}
701
 
702
/**
703
 * class Auth_RADIUS_MSCHAPv1
704
 *
705
 * Class for authenticating using MS-CHAPv1 see RFC2433
706
 *
707
 * @package Auth_RADIUS
708
 */
709
class Auth_RADIUS_MSCHAPv1 extends Auth_RADIUS_CHAP_MD5
710
{
711
    /**
712
     * LAN-Manager-Response
713
     * @var  string
714
     */
715
    var $lmResponse = null;
716
 
717
    /**
718
     * Wether using deprecated LM-Responses or not.
719
     * 0 = use LM-Response, 1 = use NT-Response
720
     * @var  bool
721
     */
722
    var $flags = 1;
723
 
724
    /**
725
     * Put MS-CHAPv1 specific attributes
726
     *
727
     * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge
728
     * and the response. The response has this structure:
729
     * struct rad_mschapvalue {
730
     *   u_char ident;
731
     *   u_char flags;
732
     *   u_char lm_response[24];
733
     *   u_char response[24];
734
     * };
735
     *
736
     * @return void
737
     */
738
    function putAuthAttributes()
739
    {
740
        if (isset($this->username)) {
741
            $this->putAttribute(RADIUS_USER_NAME, $this->username);
742
        }
743
        if (isset($this->response) || isset($this->lmResponse)) {
744
            $lmResp = isset($this->lmResponse) ? $this->lmResponse : str_repeat ("\0", 24);
745
            $ntResp = isset($this->response)   ? $this->response :   str_repeat ("\0", 24);
746
            $resp = pack('CC', $this->chapid, $this->flags) . $lmResp . $ntResp;
747
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_RESPONSE, $resp);
748
        }
749
        if (isset($this->challenge)) {
750
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
751
        }
752
    }
753
}
754
 
755
/**
756
 * class Auth_RADIUS_MSCHAPv2
757
 *
758
 * Class for authenticating using MS-CHAPv2 see RFC2759
759
 *
760
 * @package Auth_RADIUS
761
 */
762
class Auth_RADIUS_MSCHAPv2 extends Auth_RADIUS_MSCHAPv1
763
{
764
    /**
765
     * 16 Bytes binary challenge
766
     * @var  string
767
     */
768
    var $challenge = null;
769
 
770
    /**
771
     * 16 Bytes binary Peer Challenge
772
     * @var  string
773
     */
774
    var $peerChallenge = null;
775
 
776
  /**
777
     * Put MS-CHAPv2 specific attributes
778
     *
779
     * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge
780
     * and the response. The response has this structure:
781
     * struct rad_mschapv2value {
782
     *   u_char ident;
783
     *   u_char flags;
784
     *   u_char pchallenge[16];
785
     *   u_char reserved[8];
786
     *   u_char response[24];
787
     * };
788
     * where pchallenge is the peer challenge. Like for MS-CHAPv1 we set the flags field to 1.
789
     * @return void
790
     */
791
    function putAuthAttributes()
792
    {
793
        if (isset($this->username)) {
794
            $this->putAttribute(RADIUS_USER_NAME, $this->username);
795
        }
796
        if (isset($this->response) && isset($this->peerChallenge)) {
797
            // Response: chapid, flags (1 = use NT Response), Peer challenge, reserved, Response
798
            $resp = pack('CCa16a8a24',$this->chapid , 1, $this->peerChallenge, str_repeat("\0", 8), $this->response);
799
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP2_RESPONSE, $resp);
800
        }
801
        if (isset($this->challenge)) {
802
            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
803
        }
804
    }
805
 
806
    /**
807
     * Frees resources.
808
     *
809
     * Calling this method is always a good idea, because all security relevant
810
     * attributes are filled with Nullbytes to leave nothing in the mem.
811
     *
812
     * @access public
813
     */
814
    function close()
815
    {
816
        Auth_RADIUS_MSCHAPv1::close();
817
        $this->peerChallenge = str_repeat("\0", strlen($this->peerChallenge));
818
    }
819
}
820
 
821
/**
822
 * class Auth_RADIUS_Acct
823
 *
824
 * Class for RADIUS accounting
825
 *
826
 * @package Auth_RADIUS
827
 */
828
class Auth_RADIUS_Acct extends Auth_RADIUS
829
{
830
    /**
831
     * Defines where the Authentication was made, possible values are:
832
     * RADIUS_AUTH_RADIUS, RADIUS_AUTH_LOCAL, RADIUS_AUTH_REMOTE
833
     * @var  integer
834
     */
835
    var $authentic = null;
836
 
837
   /**
838
     * Defines the type of the accounting request, on of:
839
     * RADIUS_START, RADIUS_STOP, RADIUS_ACCOUNTING_ON, RADIUS_ACCOUNTING_OFF
840
     * @var  integer
841
     */
842
    var $status_type = null;
843
 
844
   /**
845
     * The time the user was logged in in seconds
846
     * @var  integer
847
     */
848
    var $session_time = null;
849
 
850
   /**
851
     * A uniq identifier for the session of the user, maybe the PHP-Session-Id
852
     * @var  string
853
     */
854
    var $session_id = null;
855
 
856
    /**
857
     * Constructor
858
     *
859
     * Generates a predefined session_id. We use the Remote-Address, the PID, and the Current user.
860
     * @return void
861
     */
862
    function Auth_RADIUS_Acct()
863
    {
864
        $this->Auth_RADIUS();
865
 
866
        if (isset($_SERVER)) {
867
            $var = &$_SERVER;
868
        } else {
869
            $var = &$GLOBALS['HTTP_SERVER_VARS'];
870
        }
871
 
872
        $this->session_id = sprintf("%s:%d-%s", isset($var['REMOTE_ADDR']) ? $var['REMOTE_ADDR'] : '127.0.0.1' , getmypid(), get_current_user());
873
    }
874
 
875
    /**
876
     * Creates a RADIUS resource
877
     *
878
     * Creates a RADIUS resource for accounting. This should be the first
879
     * call before you make any other things with the library.
880
     *
881
     * @return bool   true on success, false on error
882
     */
883
    function open()
884
    {
885
        $this->res = radius_acct_open();
886
        if (!$this->res) {
887
            return false;
888
        }
889
        return true;
890
    }
891
 
892
   /**
893
     * Creates an accounting request
894
     *
895
     * Creates an accounting request.
896
     * You MUST call this method before you can put any attribute.
897
     *
898
     * @return bool   true on success, false on error
899
     */
900
    function createRequest()
901
    {
902
        if (!radius_create_request($this->res, RADIUS_ACCOUNTING_REQUEST)) {
903
            return false;
904
        }
905
        return true;
906
    }
907
 
908
  /**
909
     * Put attributes for accounting.
910
     *
911
     * Here we put some accounting values. There many more attributes for accounting,
912
     * but for web-applications only certain attributes make sense.
913
     * @return void
914
     */
915
    function putAuthAttributes()
916
    {
917
        $this->putAttribute(RADIUS_ACCT_SESSION_ID, $this->session_id);
918
        $this->putAttribute(RADIUS_ACCT_STATUS_TYPE, $this->status_type);
919
        if (isset($this->session_time) && $this->status_type == RADIUS_STOP) {
920
            $this->putAttribute(RADIUS_ACCT_SESSION_TIME, $this->session_time);
921
        }
922
        if (isset($this->authentic)) {
923
            $this->putAttribute(RADIUS_ACCT_AUTHENTIC, $this->authentic);
924
        }
925
 
926
    }
927
 
928
}
929
 
930
/**
931
 * class Auth_RADIUS_Acct_Start
932
 *
933
 * Class for RADIUS accounting. Its usualy used, after the user has logged in.
934
 *
935
 * @package Auth_RADIUS
936
 */
937
class Auth_RADIUS_Acct_Start extends Auth_RADIUS_Acct
938
{
939
   /**
940
     * Defines the type of the accounting request.
941
     * It is set to RADIUS_START by default in this class.
942
     * @var  integer
943
     */
944
    var $status_type = Auth_RADIUS_Acct_Stop;
945
}
946
 
947
/**
948
 * class Auth_RADIUS_Acct_Start
949
 *
950
 * Class for RADIUS accounting. Its usualy used, after the user has logged out.
951
 *
952
 * @package Auth_RADIUS
953
 */
954
class Auth_RADIUS_Acct_Stop extends Auth_RADIUS_Acct
955
{
956
   /**
957
     * Defines the type of the accounting request.
958
     * It is set to RADIUS_STOP by default in this class.
959
     * @var  integer
960
     */
961
    var $status_type = RADIUS_STOP;
962
}
963
 
964
?>