Source for file RADIUS.php
Documentation is available at RADIUS.php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
Copyright (c) 2003, Michael Bretterklieber <michael@bretterklieber.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This code cannot simply be copied and put under the GNU Public License or
any other GPL-like (LGPL, GPL2) License.
$Id: RADIUS.php,v 1.5 2004/03/25 15:48:40 mbretter Exp $
* Client implementation of RADIUS. This are wrapper classes for
* Provides RADIUS Authentication (RFC2865) and RADIUS Accounting (RFC2866).
* @author Michael Bretterklieber <michael@bretterklieber.com>
* @version $Revision: 1.5 $
PEAR ::loadExtension ('radius');
* Abstract base class for RADIUS
* List of RADIUS servers.
* @see addServer(), putServer()
* Path to the configuration-file.
* Username for authentication and accounting requests.
* Password for plaintext-authentication (PAP).
* List of known attributes.
* @see dumpAttributes(), getAttributes()
* List of raw attributes.
* @see dumpAttributes(), getAttributes()
* List of raw vendor specific attributes.
* @see dumpAttributes(), getAttributes()
* Loads the RADIUS PECL/extension
* Adds a RADIUS server to the list of servers for requests.
* At most 10 servers may be specified. When multiple servers
* are given, they are tried in round-robin fashion until a
* valid response is received
* @param string $servername Servername or IP-Address
* @param integer $port Portnumber
* @param string $sharedSecret Shared secret
* @param integer $timeout Timeout for each request
* @param integer $maxtries Max. retries for each request
function addServer($servername = 'localhost', $port = 0 , $sharedSecret = 'testing123', $timeout = 3 , $maxtries = 3 )
$this->_servers[] = array ($servername, $port, $sharedSecret, $timeout, $maxtries);
* Returns an error message, if an error occurred.
return radius_strerror ($this->res);
* Sets the configuration-file.
* @param string $file Path to the configuration file
$this->_configfile = $file;
* @param integer $attrib Attribute-number
* @param mixed $port Attribute-value
* @param type $type Attribute-type
* @return bool true on success, false on error
return radius_put_int ($this->res, $attrib, $value);
return radius_put_addr ($this->res, $attrib, $value);
return radius_put_attr ($this->res, $attrib, $value);
* Puts a vendor-specific attribute.
* @param integer $vendor Vendor (MSoft, Cisco, ...)
* @param integer $attrib Attribute-number
* @param mixed $port Attribute-value
* @param type $type Attribute-type
* @return bool true on success, false on error
return radius_put_vendor_int ($this->res, $vendor, $attrib, $value);
return radius_put_vendor_addr ($this->res, $vendor,$attrib, $value);
return radius_put_vendor_attr ($this->res, $vendor, $attrib, $value);
* Prints known attributes received from the server.
echo " $name:$data<br>\n";
* Puts standard attributes.
$var = &$GLOBALS['HTTP_SERVER_VARS'];
$this->putAttribute(RADIUS_NAS_IDENTIFIER , isset ($var['HTTP_HOST']) ? $var['HTTP_HOST'] : 'localhost');
$this->putAttribute(RADIUS_CALLING_STATION_ID , isset ($var['REMOTE_HOST']) ? $var['REMOTE_HOST'] : '127.0.0.1');
* Puts custom attributes.
* Configures the radius library.
* @param string $servername Servername or IP-Address
* @param integer $port Portnumber
* @param string $sharedSecret Shared secret
* @param integer $timeout Timeout for each request
* @param integer $maxtries Max. retries for each request
* @return bool true on success, false on error
function putServer($servername, $port = 0 , $sharedsecret = 'testing123', $timeout = 3 , $maxtries = 3 )
if (!radius_add_server ($this->res, $servername, $port, $sharedsecret, $timeout, $maxtries)) {
* Configures the radius library via external configurationfile
* @param string $servername Servername or IP-Address
* @return bool true on success, false on error
if (!radius_config ($this->res, $file)) {
* Initiates a RADIUS request.
* @return bool true on success, false on errors
foreach ($this->_servers as $s) {
// Servername, port, sharedsecret, timeout, retries
if (!$this->putServer($s[0 ], $s[1 ], $s[2 ], $s[3 ], $s[4 ])) {
if (!empty ($this->_configfile)) {
* Sends a prepared RADIUS request and waits for a response
* @return mixed true on success, false on reject, PEAR_Error on error
$req = radius_send_request ($this->res);
return $this->raiseError ('Error sending request: ' . $this->getError());
case RADIUS_ACCESS_ACCEPT:
return $this->raiseError ('RADIUS_ACCESS_ACCEPT is unexpected for accounting');
case RADIUS_ACCESS_REJECT:
case RADIUS_ACCOUNTING_RESPONSE:
return $this->raiseError ('RADIUS_ACCOUNTING_RESPONSE is unexpected for authentication');
return $this->raiseError (" Unexpected return value: $req" );
* Reads all received attributes after sending the request.
* This methos stores know attributes in the property attributes,
* all attributes (including known attibutes) are stored in rawAttributes
* or rawVendorAttributes.
* NOTE: call this functio also even if the request was rejected, because the
* Server returns usualy an errormessage
* @return bool true on success, false on error
while ($attrib = radius_get_attr ($this->res)) {
case RADIUS_FRAMED_IP_ADDRESS:
$this->attributes['framed_ip'] = radius_cvt_addr ($data);
case RADIUS_FRAMED_IP_NETMASK:
$this->attributes['framed_mask'] = radius_cvt_addr ($data);
$this->attributes['framed_mtu'] = radius_cvt_int ($data);
case RADIUS_FRAMED_COMPRESSION:
$this->attributes['framed_compression'] = radius_cvt_int ($data);
case RADIUS_SESSION_TIMEOUT:
$this->attributes['session_timeout'] = radius_cvt_int ($data);
case RADIUS_IDLE_TIMEOUT:
$this->attributes['idle_timeout'] = radius_cvt_int ($data);
case RADIUS_SERVICE_TYPE:
$this->attributes['service_type'] = radius_cvt_int ($data);
$this->attributes['class'] = radius_cvt_int ($data);
case RADIUS_FRAMED_PROTOCOL:
$this->attributes['framed_protocol'] = radius_cvt_int ($data);
case RADIUS_FRAMED_ROUTING:
$this->attributes['framed_routing'] = radius_cvt_int ($data);
$this->attributes['filter_id'] = radius_cvt_string ($data);
case RADIUS_VENDOR_SPECIFIC:
$attribv = radius_get_vendor_attr ($data);
$vendor = $attribv['vendor'];
$attrv = $attribv['attr'];
$datav = $attribv['data'];
if ($vendor == RADIUS_VENDOR_MICROSOFT ) {
case RADIUS_MICROSOFT_MS_CHAP2_SUCCESS:
$this->attributes['ms_chap2_success'] = radius_cvt_string ($datav);
case RADIUS_MICROSOFT_MS_CHAP_ERROR:
case RADIUS_MICROSOFT_MS_CHAP_DOMAIN:
$this->attributes['ms_chap_domain'] = radius_cvt_string ($datav);
case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
$this->attributes['ms_mppe_encryption_policy'] = radius_cvt_int ($datav);
case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
$this->attributes['ms_mppe_encryption_types'] = radius_cvt_int ($datav);
case RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS:
$demangled = radius_demangle ($this->res, $datav);
$this->attributes['ms_chap_mppe_nt_key'] = substr($demangled, 8 , RADIUS_MPPE_KEY_LEN );
case RADIUS_MICROSOFT_MS_MPPE_SEND_KEY:
$this->attributes['ms_chap_mppe_send_key'] = radius_demangle_mppe_key ($this->res, $datav);
case RADIUS_MICROSOFT_MS_MPPE_RECV_KEY:
$this->attributes['ms_chap_mppe_recv_key'] = radius_demangle_mppe_key ($this->res, $datav);
case RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER:
$this->attributes['ms_primary_dns_server'] = radius_cvt_string ($datav);
* Calling this method is always a good idea, because all security relevant
* attributes are filled with Nullbytes to leave nothing in the mem.
if ($this->res != null ) {
radius_close ($this->res);
* Class for authenticating using PAP (Plaintext)
* @param string $username Username
* @param string $password Password
* Creates a RADIUS resource
* Creates a RADIUS resource for authentication. This should be the first
* call before you make any other things with the library.
* @return bool true on success, false on error
$this->res = radius_auth_open ();
* Creates an authentication request
* Creates an authentication request.
* You MUST call this method before you can put any attribute
* @return bool true on success, false on error
if (!radius_create_request ($this->res, RADIUS_ACCESS_REQUEST )) {
* Put authentication specific attributes
* class Auth_RADIUS_CHAP_MD5
* Class for authenticating using CHAP-MD5 see RFC1994.
* Instead og the plaintext password the challenge and
* the response are needed.
* 8 Bytes binary challenge
* 16 Bytes MD5 response binary
* Id of the authentication request. Should incremented after every request.
* @param string $username Username
* @param string $challenge 8 Bytes Challenge (binary)
* @param integer $chapid Requestnumber
* Put CHAP-MD5 specific attributes
* For authenticating using CHAP-MD5 via RADIUS you have to put the challenge
* and the response. The chapid is inserted in the first byte of the response.
* Calling this method is always a good idea, because all security relevant
* attributes are filled with Nullbytes to leave nothing in the mem.
* class Auth_RADIUS_MSCHAPv1
* Class for authenticating using MS-CHAPv1 see RFC2433
* Wether using deprecated LM-Responses or not.
* 0 = use LM-Response, 1 = use NT-Response
* Put MS-CHAPv1 specific attributes
* For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge
* and the response. The response has this structure:
* struct rad_mschapvalue {
* u_char lm_response[24];
$this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT , RADIUS_MICROSOFT_MS_CHAP_RESPONSE , $resp);
* class Auth_RADIUS_MSCHAPv2
* Class for authenticating using MS-CHAPv2 see RFC2759
* 16 Bytes binary challenge
* 16 Bytes binary Peer Challenge
* Put MS-CHAPv2 specific attributes
* For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge
* and the response. The response has this structure:
* struct rad_mschapv2value {
* where pchallenge is the peer challenge. Like for MS-CHAPv1 we set the flags field to 1.
// Response: chapid, flags (1 = use NT Response), Peer challenge, reserved, Response
$this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT , RADIUS_MICROSOFT_MS_CHAP2_RESPONSE , $resp);
* Calling this method is always a good idea, because all security relevant
* attributes are filled with Nullbytes to leave nothing in the mem.
* Class for RADIUS accounting
* Defines where the Authentication was made, possible values are:
* RADIUS_AUTH_RADIUS, RADIUS_AUTH_LOCAL, RADIUS_AUTH_REMOTE
* Defines the type of the accounting request, on of:
* RADIUS_START, RADIUS_STOP, RADIUS_ACCOUNTING_ON, RADIUS_ACCOUNTING_OFF
* The time the user was logged in in seconds
* A uniq identifier for the session of the user, maybe the PHP-Session-Id
* Generates a predefined session_id. We use the Remote-Address, the PID, and the Current user.
$var = &$GLOBALS['HTTP_SERVER_VARS'];
* Creates a RADIUS resource
* Creates a RADIUS resource for accounting. This should be the first
* call before you make any other things with the library.
* @return bool true on success, false on error
$this->res = radius_acct_open ();
* Creates an accounting request
* Creates an accounting request.
* You MUST call this method before you can put any attribute.
* @return bool true on success, false on error
if (!radius_create_request ($this->res, RADIUS_ACCOUNTING_REQUEST )) {
* Put attributes for accounting.
* Here we put some accounting values. There many more attributes for accounting,
* but for web-applications only certain attributes make sense.
* class Auth_RADIUS_Acct_Start
* Class for RADIUS accounting. Its usualy used, after the user has logged in.
* Defines the type of the accounting request.
* It is set to RADIUS_START by default in this class.
* class Auth_RADIUS_Acct_Start
* Class for RADIUS accounting. Its usualy used, after the user has logged out.
* Defines the type of the accounting request.
* It is set to RADIUS_STOP by default in this class.
* class Auth_RADIUS_Acct_Update
* Class for interim RADIUS accounting updates.
* Defines the type of the accounting request.
* It is set to RADIUS_UPDATE by default in this class.
Documentation generated on Mon, 11 Mar 2019 10:14:10 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|