130 lines
4.8 KiB
PHP
130 lines
4.8 KiB
PHP
<?php
|
|
/**
|
|
* Copyright 2002-2017 Horde LLC (http://www.horde.org/)
|
|
*
|
|
* See the enclosed file COPYING for license information (LGPL). If you did
|
|
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
|
*
|
|
* @author Michael Slusarz <slusarz@horde.org>
|
|
* @category Horde
|
|
* @license http://www.horde.org/licenses/lgpl21 LGPL-2.1
|
|
* @package Auth
|
|
*/
|
|
|
|
/**
|
|
* The Horde_Auth_Radius class provides a RADIUS implementation of the Horde
|
|
* authentication system.
|
|
*
|
|
* This class requires the 'radius' PECL extension:
|
|
* http://pecl.php.net/package/radius
|
|
*
|
|
* @author Michael Slusarz <slusarz@horde.org>
|
|
* @category Horde
|
|
* @copyright 2002-2017 Horde LLC
|
|
* @license http://www.horde.org/licenses/lgpl21 LGPL-2.1
|
|
* @package Auth
|
|
*/
|
|
class Horde_Auth_Radius extends Horde_Auth_Base
|
|
{
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param array $params Connection parameters.
|
|
* <pre>
|
|
* 'host' - (string) [REQUIRED] The RADIUS host to use (IP address or
|
|
* fully qualified hostname).
|
|
* 'method' - (string) [REQUIRED] The RADIUS method to use for validating
|
|
* the request.
|
|
* Either: 'PAP', 'CHAP_MD5', 'MSCHAPv1', or 'MSCHAPv2'.
|
|
* ** CURRENTLY, only 'PAP' is supported. **
|
|
* 'nas' - (string) The RADIUS NAS identifier to use.
|
|
* DEFAULT: The value of $_SERVER['HTTP_HOST'] or, if not
|
|
* defined, then 'localhost'.
|
|
* 'port' - (integer) The port to use on the RADIUS server.
|
|
* DEFAULT: Whatever the local system identifies as the
|
|
* 'radius' UDP port
|
|
* 'retries' - (integer) The maximum number of repeated requests to make
|
|
* before giving up.
|
|
* DEFAULT: 3
|
|
* 'secret' - (string) [REQUIRED] The RADIUS shared secret string for the
|
|
* host. The RADIUS protocol ignores all but the leading 128
|
|
* bytes of the shared secret.
|
|
* 'suffix' - (string) The domain name to add to unqualified user names.
|
|
* DEFAULT: NONE
|
|
* 'timeout' - (integer) The timeout for receiving replies from the server
|
|
* (in seconds).
|
|
* DEFAULT: 3
|
|
* </pre>
|
|
*
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function __construct(array $params = array())
|
|
{
|
|
if (!Horde_Util::extensionExists('radius')) {
|
|
throw new Horde_Auth_Exception(__CLASS__ . ': requires the radius PECL extension to be loaded.');
|
|
}
|
|
|
|
foreach (array('host', 'secret', 'method') as $val) {
|
|
if (!isset($params[$val])) {
|
|
throw new InvalidArgumentException('Missing ' . $val . ' parameter.');
|
|
}
|
|
}
|
|
|
|
$params = array_merge(array(
|
|
'nas' => (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'),
|
|
'port' => 0,
|
|
'retries' => 3,
|
|
'suffix' => '',
|
|
'timeout' => 3
|
|
), $params);
|
|
|
|
parent::__construct($params);
|
|
}
|
|
|
|
/**
|
|
* Find out if a set of login credentials are valid.
|
|
*
|
|
* @param string $username The userId to check.
|
|
* @param array $credentials An array of login credentials.
|
|
* For radius, this must contain a password
|
|
* entry.
|
|
*
|
|
* @throws Horde_Auth_Exception
|
|
*/
|
|
protected function _authenticate($username, $credentials)
|
|
{
|
|
/* Password is required. */
|
|
if (!isset($credentials['password'])) {
|
|
throw new Horde_Auth_Exception('Password required for RADIUS authentication.');
|
|
}
|
|
|
|
$res = radius_auth_open();
|
|
radius_add_server($res, $this->_params['host'], $this->_params['port'], $this->_params['secret'], $this->_params['timeout'], $this->_params['retries']);
|
|
radius_create_request($res, RADIUS_ACCESS_REQUEST);
|
|
radius_put_attr($res, RADIUS_NAS_IDENTIFIER, $this->_params['nas']);
|
|
radius_put_attr($res, RADIUS_NAS_PORT_TYPE, RADIUS_VIRTUAL);
|
|
radius_put_attr($res, RADIUS_SERVICE_TYPE, RADIUS_FRAMED);
|
|
radius_put_attr($res, RADIUS_FRAMED_PROTOCOL, RADIUS_PPP);
|
|
radius_put_attr($res, RADIUS_CALLING_STATION_ID, isset($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : '127.0.0.1');
|
|
|
|
/* Insert username/password into request. */
|
|
radius_put_attr($res, RADIUS_USER_NAME, $username);
|
|
radius_put_attr($res, RADIUS_USER_PASSWORD, $credentials['password']);
|
|
|
|
/* Send request. */
|
|
$success = radius_send_request($res);
|
|
|
|
switch ($success) {
|
|
case RADIUS_ACCESS_ACCEPT:
|
|
break;
|
|
|
|
case RADIUS_ACCESS_REJECT:
|
|
throw new Horde_Auth_Exception('Authentication rejected by RADIUS server.');
|
|
|
|
default:
|
|
throw new Horde_Auth_Exception(radius_strerror($res));
|
|
}
|
|
}
|
|
|
|
}
|