Skip to content
Snippets Groups Projects
Commit 334c12cd authored by Olav Morken's avatar Olav Morken
Browse files

New authentication module: radius:Radius.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1440 44740490-163a-0410-bde0-09ae8108e29a
parent c503400b
No related branches found
No related tags found
No related merge requests found
RADIUS module
=============
The RADIUS module provides a single authentication module:
`radius:Radius`
: Authenticate a user against a RADIUS server.
This authentication module contacts a RADIUS server, and authenticates
the user by using username & password authentication.
To use this module, enable the radius module by creating a file named
`enable` in the `modules/radius/`-directory. Then you need to add a
authentication source which uses the `radius:Radius` module to
`config/authsources.php`:
'example-radius' => array(
'radius:Radius',
/*
* The hostname of the RADIUS server.
* Required.
*/
'hostname' => 'radius.example.org',
/*
* The port number of the radius server.
* Optional, defaults to 1812.
*/
'port' => 1812,
/*
* The shared secret which is used when contacting the RADUIS server.
* Required.
*/
'secret' => 'topsecret',
/*
* The timeout for contacting the RADIUS server, in seconds.
* Optional, defaults to 5 seconds.
*/
'timeout' => 5,
/*
* The number of times we should retry connections to the RADIUS server.
* Optional, defaults to 3 attempts.
*/
'retries' => 3,
/*
* The attribute name we should store the username in. Ths username
* will not be saved in any attribute if this is NULL.
* Optional, defaults to NULL.
*/
'username_attribute' => 'eduPersonPrincipalName',
),
User attributes
---------------
If the RADIUS server is configured to include attributes for the user in
the response, this module may be able to extract them. This requires the
attributes to be stored in a vendor-specific attribute in the response
from the RADIUS server.
The code expects one vendor-attribute with a specific vendor and a specific
vendor attribute type for each user attribute. The vendor-attribute must
contain a value on the form <name>=<value>.
The following configuration options are available for user attributes:
/*
* This is the vendor for the vendor-specific attribute which contains
* the attributes for this user. This can be NULL if no attributes are
* included in the response.
* Optional, defaults to NULL.
*/
'attribute_vendor' => 23735,
/*
* The vendor attribute-type of the attribute which contains the
* attributes for the user.
* Required if 'vendor' is set.
*/
'attribute_vendor_type' => 4,
<?php
/**
* RADIUS authentication source.
*
* This class is based on www/auth/login-radius.php.
*
* @package simpleSAMLphp
* @version $Id$
*/
class sspmod_radius_Auth_Source_Radius extends sspmod_core_Auth_UserPassBase {
/**
* The hostname of the radius server.
*/
private $hostname;
/**
* The port of the radius server.
*/
private $port;
/**
* The secret used when communicating with the radius server.
*/
private $secret;
/**
* The timeout for contacting the radius server.
*/
private $timeout;
/**
* The number of retries which should be attempted.
*/
private $retries;
/**
* The attribute name where the username should be stored.
*/
private $usernameAttribute;
/**
* The vendor for the RADIUS attributes we are interrested in.
*/
private $vendor;
/**
* The vendor-specific attribute for the RADIUS attributes we are interrested in.
*/
private $vendorType;
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public function __construct($info, $config) {
assert('is_array($info)');
assert('is_array($config)');
/* Call the parent constructor first, as required by the interface. */
parent::__construct($info, $config);
/* Parse configuration. */
$config = SimpleSAML_Configuration::loadFromArray($config,
'Authentication source ' . var_export($this->authId, TRUE));
$this->hostname = $config->getString('hostname');
$this->port = $config->getIntegerRange('port', 1, 65535, 1812);
$this->secret = $config->getString('secret');
$this->timeout = $config->getInteger('timeout', 5);
$this->retries = $config->getInteger('retries', 3);
$this->usernameAttribute = $config->getString('username_attribute', NULL);
$this->vendor = $config->getInteger('attribute_vendor', NULL);
if ($this->vendor !== NULL) {
$this->vendorType = $config->getInteger('attribute_vendor_type');
}
}
/**
* Attempt to log in using the given username and password.
*
* @param string $username The username the user wrote.
* @param string $password The password the user wrote.
* @return array Associative array with the users attributes.
*/
protected function login($username, $password) {
assert('is_string($username)');
assert('is_string($password)');
$radius = radius_auth_open();
if (!radius_add_server($radius, $this->hostname, $this->port, $this->secret, $this->timeout, $this->retries)) {
throw new Exception('Error connecting to radius server: ' . radius_strerror($radius));
}
if (!radius_create_request($radius, RADIUS_ACCESS_REQUEST)) {
throw new Exception('Error creating radius request: ' . radius_strerror($radius));
}
radius_put_attr($radius, RADIUS_USER_NAME, $username);
radius_put_attr($radius, RADIUS_USER_PASSWORD, $password);
$res = radius_send_request($radius);
if ($res != RADIUS_ACCESS_ACCEPT) {
switch ($res) {
case RADIUS_ACCESS_REJECT:
/* Invalid username or password. */
throw new SimpleSAML_Error_Error('WRONGUSERPASS');
case RADIUS_ACCESS_CHALLENGE:
throw new Exception('Radius authentication error: Challenge requested, but not supported.');
default:
throw new Exception('Error during radius authentication: ' . radius_strerror($radius));
}
}
/* If we get this far, we have a valid login. */
$attributes = array();
if ($this->usernameAttribute !== NULL) {
$attributes[$this->usernameAttribute] = array($username);
}
if ($this->vendor === NULL) {
/*
* We aren't interrested in any vendor-specific attributes. We are
* therefore done now.
*/
return $attributes;
}
/* get AAI attribute sets. Contributed by Stefan Winter, (c) RESTENA */
while ($resa = radius_get_attr($radius)) {
if (!is_array($resa)) {
throw new Exception('Error getting radius attributes: ' . radius_strerror($radius));
}
if ($resa['attr'] !== RADIUS_VENDOR_SPECIFIC) {
continue;
}
$resv = radius_get_vendor_attr($resa['data']);
if (!is_array($resv)) {
throw new Exception('Error getting vendor specific attribute: ' . radius_strerror($radius));
}
$vendor = $resv['vendor'];
$attrv = $resv['attr'];
$datav = $resv['data'];
/*
* Uncomment this to debug vendor attributes.
*/
//printf("Got Vendor Attr:%d %d Bytes %s<br/>", $attrv, strlen($datav), bin2hex($datav));
if ($vendor != $this->vendor || $attrv != $this->vendorType) {
continue;
}
$attrib_name = strtok($datav,'=');
$attrib_value = strtok('=');
/* if the attribute name is already in result set, add another value */
if (array_key_exists($attrib_name, $attributes)) {
$attributes[$attrib_name][] = $attrib_value;
} else {
$attributes[$attrib_name] = array($attrib_value);
}
}
/* end of contribution */
return $attributes;
}
}
?>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment