1<?php
2/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
3
4/**
5 * Storage driver for use against RADIUS servers
6 *
7 * PHP versions 4 and 5
8 *
9 * LICENSE: This source file is subject to version 3.01 of the PHP license
10 * that is available through the world-wide-web at the following URI:
11 * http://www.php.net/license/3_01.txt.  If you did not receive a copy of
12 * the PHP License and are unable to obtain it through the web, please
13 * send a note to license@php.net so we can mail you a copy immediately.
14 *
15 * @category   Authentication
16 * @package    Auth
17 * @author     Michael Bretterklieber <michael@bretterklieber.com>
18 * @author     Adam Ashley <aashley@php.net>
19 * @copyright  2001-2006 The PHP Group
20 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
21 * @version    CVS: $Id: RADIUS.php 237449 2007-06-12 03:11:27Z aashley $
22 * @link       http://pear.php.net/package/Auth
23 * @since      File available since Release 1.2.0
24 */
25
26/**
27 * Include Auth_Container base class
28 */
29require_once "Auth/Container.php";
30/**
31 * Include PEAR Auth_RADIUS package
32 */
33require_once "Auth/RADIUS.php";
34
35/**
36 * Storage driver for authenticating users against RADIUS servers.
37 *
38 * @category   Authentication
39 * @package    Auth
40 * @author     Michael Bretterklieber <michael@bretterklieber.com>
41 * @author     Adam Ashley <aashley@php.net>
42 * @copyright  2001-2006 The PHP Group
43 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
44 * @version    Release: @package_version@  File: $Revision: 237449 $
45 * @link       http://pear.php.net/package/Auth
46 * @since      Class available since Release 1.2.0
47 */
48class Auth_Container_RADIUS extends Auth_Container
49{
50
51    // {{{ properties
52
53    /**
54     * Contains a RADIUS object
55     * @var object
56     */
57    var $radius;
58
59    /**
60     * Contains the authentication type
61     * @var string
62     */
63    var $authtype;
64
65    // }}}
66    // {{{ Auth_Container_RADIUS() [constructor]
67
68    /**
69     * Constructor of the container class.
70     *
71     * $options can have these keys:
72     * 'servers'    an array containing an array: servername, port,
73     *              sharedsecret, timeout, maxtries
74     * 'configfile' The filename of the configuration file
75     * 'authtype'   The type of authentication, one of: PAP, CHAP_MD5,
76     *              MSCHAPv1, MSCHAPv2, default is PAP
77     *
78     * @param  $options associative array
79     * @return object Returns an error object if something went wrong
80     */
81    function Auth_Container_RADIUS($options)
82    {
83        $this->authtype = 'PAP';
84        if (isset($options['authtype'])) {
85            $this->authtype = $options['authtype'];
86        }
87        $classname = 'Auth_RADIUS_' . $this->authtype;
88        if (!class_exists($classname)) {
89            PEAR::raiseError("Unknown Authtype, please use one of: "
90                    ."PAP, CHAP_MD5, MSCHAPv1, MSCHAPv2!", 41, PEAR_ERROR_DIE);
91        }
92
93        $this->radius = new $classname;
94
95        if (isset($options['configfile'])) {
96            $this->radius->setConfigfile($options['configfile']);
97        }
98
99        $servers = $options['servers'];
100        if (is_array($servers)) {
101            foreach ($servers as $server) {
102                $servername     = $server[0];
103                $port           = isset($server[1]) ? $server[1] : 0;
104                $sharedsecret   = isset($server[2]) ? $server[2] : 'testing123';
105                $timeout        = isset($server[3]) ? $server[3] : 3;
106                $maxtries       = isset($server[4]) ? $server[4] : 3;
107                $this->radius->addServer($servername, $port, $sharedsecret, $timeout, $maxtries);
108            }
109        }
110
111        if (!$this->radius->start()) {
112            PEAR::raiseError($this->radius->getError(), 41, PEAR_ERROR_DIE);
113        }
114    }
115
116    // }}}
117    // {{{ fetchData()
118
119    /**
120     * Authenticate
121     *
122     * @param  string Username
123     * @param  string Password
124     * @return bool   true on success, false on reject
125     */
126    function fetchData($username, $password, $challenge = null)
127    {
128        $this->log('Auth_Container_RADIUS::fetchData() called.', AUTH_LOG_DEBUG);
129
130        switch($this->authtype) {
131            case 'CHAP_MD5':
132            case 'MSCHAPv1':
133                if (isset($challenge)) {
134                    $this->radius->challenge = $challenge;
135                    $this->radius->chapid    = 1;
136                    $this->radius->response  = pack('H*', $password);
137                } else {
138                    require_once 'Crypt/CHAP.php';
139                    $classname = 'Crypt_' . $this->authtype;
140                    $crpt = new $classname;
141                    $crpt->password = $password;
142                    $this->radius->challenge = $crpt->challenge;
143                    $this->radius->chapid    = $crpt->chapid;
144                    $this->radius->response  = $crpt->challengeResponse();
145                }
146                break;
147
148            case 'MSCHAPv2':
149                require_once 'Crypt/CHAP.php';
150                $crpt = new Crypt_MSCHAPv2;
151                $crpt->username = $username;
152                $crpt->password = $password;
153                $this->radius->challenge     = $crpt->authChallenge;
154                $this->radius->peerChallenge = $crpt->peerChallenge;
155                $this->radius->chapid        = $crpt->chapid;
156                $this->radius->response      = $crpt->challengeResponse();
157                break;
158
159            default:
160                $this->radius->password = $password;
161                break;
162        }
163
164        $this->radius->username = $username;
165
166        $this->radius->putAuthAttributes();
167        $result = $this->radius->send();
168        if (PEAR::isError($result)) {
169            return false;
170        }
171
172        $this->radius->getAttributes();
173//      just for debugging
174//      $this->radius->dumpAttributes();
175
176        return $result;
177    }
178
179    // }}}
180
181}
182?>
183