.\" -*- mode: troff; coding: utf-8 -*-
.\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.45)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.ie n \{\
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Required to disable full justification in groff 1.23.0.
.if n .ds AD l
.\" ========================================================================
.\"
.IX Title "Radius 3"
.TH Radius 3 2026-05-19 "perl v5.42.2" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH NAME
Authen::Radius \- provide simple Radius client facilities
.SH SYNOPSIS
.IX Header "SYNOPSIS"
.Vb 1
\& use Authen::Radius;
\&
\& $r = new Authen::Radius(Host => \*(Aqmyserver\*(Aq, Secret => \*(Aqmysecret\*(Aq);
\& print "auth result=", $r\->check_pwd(\*(Aqmyname\*(Aq, \*(Aqmypwd\*(Aq), "\en";
\&
\& $r = new Authen::Radius(Host => \*(Aqmyserver\*(Aq, Secret => \*(Aqmysecret\*(Aq);
\& Authen::Radius\->load_dictionary();
\& $r\->add_attributes (
\& { Name => \*(AqUser\-Name\*(Aq, Value => \*(Aqmyname\*(Aq },
\& { Name => \*(AqPassword\*(Aq, Value => \*(Aqmypwd\*(Aq },
\ RFC 2865 http://www.ietf.org/rfc/rfc2865.txt calls this attribute
\ User\-Password. Check your local RADIUS dictionary to find
\ out which name is used on your system
\ { Name => \*(AqUser\-Password\*(Aq, Value => \*(Aqmypwd\*(Aq },
\& { Name => \*(Aqh323\-return\-code\*(Aq, Value => \*(Aq0\*(Aq }, # Cisco AV pair
\& { Name => \*(AqDigest\-Attributes\*(Aq, Value => { Method => \*(AqREGISTER\*(Aq } }
\& );
\& $r\->send_packet(ACCESS_REQUEST) and $type = $r\->recv_packet();
\& print "server response type = $type\en";
\& for $a ($r\->get_attributes()) {
\& print "attr: name=$a\->{\*(AqName\*(Aq} value=$a\->{\*(AqValue\*(Aq}\en";
\& }
.Ve
.SH DESCRIPTION
.IX Header "DESCRIPTION"
The \f(CW\*(C`Authen::Radius\*(C'\fR module provides a simple class that allows you to
send/receive Radius requests/responses to/from a Radius server.
.SH CONSTRUCTOR
.IX Header "CONSTRUCTOR"
.IP "new ( Host => HOST, Secret => SECRET [, TimeOut => TIMEOUT] [,Service => SERVICE] [, Debug => Bool] [, LocalAddr => hostname[:port]] [,Rfc3579MessageAuth => Bool] [,NodeList= NodeListArrayRef])" 4
.IX Item "new ( Host => HOST, Secret => SECRET [, TimeOut => TIMEOUT] [,Service => SERVICE] [, Debug => Bool] [, LocalAddr => hostname[:port]] [,Rfc3579MessageAuth => Bool] [,NodeList= NodeListArrayRef])"
Creates & returns a blessed reference to a Radius object, or undef on
failure. Error status may be retrieved with \f(CW\*(C`Authen::Radius::get_error\*(C'\fR
(errorcode) or \f(CW\*(C`Authen::Radius::strerror\*(C'\fR (verbose error string).
.Sp
The default \f(CW\*(C`Service\*(C'\fR is \f(CW\*(C`radius\*(C'\fR, the alternative is \f(CW\*(C`radius\-acct\*(C'\fR.
If you do not specify port in the \f(CW\*(C`Host\*(C'\fR as a \f(CW\*(C`hostname:port\*(C'\fR, then port
specified in your \fI/etc/services\fR will be used. If there is nothing
there, and you did not specify port either then default is 1645 for
\&\f(CW\*(C`radius\*(C'\fR and 1813 for \f(CW\*(C`radius\-acct\*(C'\fR.
.Sp
Optional parameter \f(CW\*(C`Debug\*(C'\fR with a Perl "true" value turns on debugging
(verbose mode).
.Sp
Optional parameter \f(CW\*(C`LocalAddr\*(C'\fR may contain local IP/host bind address from
which RADIUS packets are sent.
.Sp
Optional parameter \f(CW\*(C`Rfc3579MessageAuth\*(C'\fR controls whether a Message\-Authenticator
attribute is generated for Access\-Request packets (RFC3579, section 3.2).
It is enabled by default to mitigate the Blast\-RADIUS protocol vulnerability
(); pass \f(CW\*(C`Rfc3579MessageAuth => 0\*(C'\fR to
disable it when talking to a server that cannot handle the attribute.
The Message\-Authenticator is always generated for Status\-Server packets.
.Sp
Optional parameter \f(CW\*(C`NodeList\*(C'\fR may contain a Perl reference to an array, containing a list of
Radius Cluster nodes. Each nodes in the list can be specified using a hostname or IP (with an optional
port number), i.e. \*(Aqradius1.mytel.com\*(Aq or \*(Aqradius.myhost.com:1812\*(Aq. Radius Cluster contains a set of Radius
servers, at any given moment of time only one server is considered to be "active"
(so requests are send to this server).
How the active node is determined? Initially in addition to the \f(CW\*(C`NodeList\*(C'\fR
parameter you may supply the \f(CW\*(C`Host\*(C'\fR parameter and specify which server should
become the first active node. If this parameter is absent, or the current
active node does not reply anymore, the process of "discovery" will be
performed: a request will be sent to all nodes and the consecutive communication
continues with the node, which will be the first to reply.
.SH METHODS
.IX Header "METHODS"
.IP "load_dictionary ( [ DICTIONARY ], [format => \*(Aqfreeradius\*(Aq | \*(Aqgnuradius\*(Aq] )" 4
.IX Item "load_dictionary ( [ DICTIONARY ], [format => 'freeradius' | 'gnuradius'] )"
Loads the definitions in the specified Radius dictionary file (standard
Livingston radiusd format). Tries to load \f(CW\*(C`/etc/raddb/dictionary\*(C'\fR when no
argument is specified, or dies. \f(CW\*(C`format\*(C'\fR should be specified if dictionary has
other format (currently supported: FreeRADIUS and GNU Radius)
.Sp
NOTE: you need to load valid dictionary if you plan to send RADIUS requests
with attributes other than just \f(CW\*(C`User\-Name\*(C'\fR/\f(CW\*(C`Password\*(C'\fR.
.IP "check_pwd ( USERNAME, PASSWORD [,NASIPADDRESS] )" 4
.IX Item "check_pwd ( USERNAME, PASSWORD [,NASIPADDRESS] )"
Checks with the RADIUS server if the specified \f(CW\*(C`PASSWORD\*(C'\fR is valid for user
\&\f(CW\*(C`USERNAME\*(C'\fR. Unless \f(CW\*(C`NASIPADDRESS\*(C'\fR is specified, the script will attempt
to determine it\*(Aqs local IP address (IP address for the RADIUS socket) and
this value will be placed in the NAS\-IP\-Address attribute.
This method is actually a wrapper for subsequent calls to
\&\f(CW\*(C`clear_attributes\*(C'\fR, \f(CW\*(C`add_attributes\*(C'\fR, \f(CW\*(C`send_packet\*(C'\fR and \f(CW\*(C`recv_packet\*(C'\fR. It
returns 1 if the \f(CW\*(C`PASSWORD\*(C'\fR is correct, or undef otherwise.
.IP "add_attributes ( { Name => NAME, Value => VALUE [, Type => TYPE] [, Vendor => VENDOR] [, Tag => TAG ] }, ... )" 4
.IX Item "add_attributes ( { Name => NAME, Value => VALUE [, Type => TYPE] [, Vendor => VENDOR] [, Tag => TAG ] }, ... )"
Adds any number of Radius attributes to the current Radius object. Attributes
are specified as a list of anon hashes. They may be \f(CW\*(C`Name\*(C'\fRd with their
dictionary name (provided a dictionary has been loaded first), or with
their raw Radius attribute\-type values. The \f(CW\*(C`Type\*(C'\fR pair should be specified
when adding attributes that are not in the dictionary (or when no dictionary
was loaded). Values for \f(CW\*(C`TYPE\*(C'\fR can be \*(Aq\f(CW\*(C`string\*(C'\fR\*(Aq, \*(Aq\f(CW\*(C`integer\*(C'\fR\*(Aq, \*(Aq\f(CW\*(C`ipaddr\*(C'\fR\*(Aq,
\&\*(Aq\f(CW\*(C`ipv6addr\*(C'\fR\*(Aq, \*(Aq\f(CW\*(C`ipv6prefix\*(C'\fR\*(Aq, \*(Aq\f(CW\*(C`ifid\*(C'\fR\*(Aq or \*(Aq\f(CW\*(C`avpair\*(C'\fR\*(Aq. The \f(CW\*(C`VENDOR\*(C'\fR may be
Vendor\*(Aqs name from the dictionary or their integer id. For tagged attributes
(RFC2868) tag can be specified in \f(CW\*(C`Name\*(C'\fR using \*(AqName:Tag\*(Aq format, or by
using \f(CW\*(C`Tag\*(C'\fR pair. TAG value is expected to be an integer, within [1:31] range
(zero value isn\*(Aqt supported).
.IP get_attributes 4
.IX Item "get_attributes"
Returns a list of references to anon hashes with the following key/value
pairs : { Name => NAME, Code => RAWTYPE, Value => VALUE, RawValue =>
RAWVALUE, Vendor => VENDOR, Tag => TAG, AttrName => NAME }. Each hash
represents an attribute in the current object. The \f(CW\*(C`Name\*(C'\fR and \f(CW\*(C`Value\*(C'\fR pairs
will contain values as translated by the dictionary (if one was loaded). The
\&\f(CW\*(C`Code\*(C'\fR and \f(CW\*(C`RawValue\*(C'\fR pairs always contain the raw attribute type & value as
received from the server. If some attribute doesn\*(Aqt exist in dictionary or
type of attribute not specified then corresponding \f(CW\*(C`Value\*(C'\fR undefined and
\&\f(CW\*(C`Name\*(C'\fR set to attribute ID (\f(CW\*(C`Code\*(C'\fR value). For tagged attribute (RFC2868), it
will include the tag into the \f(CW\*(C`NAME\*(C'\fR as \*(AqName:Tag\*(Aq. Original Name is stored in
\&\f(CW\*(C`AttrName\*(C'\fR. Also value of tag is stored in \f(CW\*(C`Tag\*(C'\fR (undef for non\-tagged
attributes).
.IP clear_attributes 4
.IX Item "clear_attributes"
Clears all attributes for the current object.
.IP "send_packet ( REQUEST_TYPE, RETRANSMIT )" 4
.IX Item "send_packet ( REQUEST_TYPE, RETRANSMIT )"
Packs up a Radius packet based on the current secret & attributes and
sends it to the server with a Request type of \f(CW\*(C`REQUEST_TYPE\*(C'\fR. Exported
\&\f(CW\*(C`REQUEST_TYPE\*(C'\fR methods are \f(CW\*(C`ACCESS_REQUEST\*(C'\fR, \f(CW\*(C`ACCESS_ACCEPT\*(C'\fR,
\&\f(CW\*(C`ACCESS_REJECT\*(C'\fR, \f(CW\*(C`ACCESS_CHALLENGE\*(C'\fR, \f(CW\*(C`ACCOUNTING_REQUEST\*(C'\fR, \f(CW\*(C`ACCOUNTING_RESPONSE\*(C'\fR,
\&\f(CW\*(C`ACCOUNTING_STATUS\*(C'\fR, \f(CW\*(C`STATUS_SERVER\*(C'\fR, \f(CW\*(C`DISCONNECT_REQUEST\*(C'\fR, \f(CW\*(C`DISCONNECT_ACCEPT\*(C'\fR,
\&\f(CW\*(C`DISCONNECT_REJECT\*(C'\fR, \f(CW\*(C`COA_REQUEST\*(C'\fR, \f(CW\*(C`COA_ACCEPT\*(C'\fR, \f(CW\*(C`COA_REJECT\*(C'\fR, \f(CW\*(C`COA_ACK\*(C'\fR,
and \f(CW\*(C`COA_NAK\*(C'\fR.
Returns the number of bytes sent, or undef on failure.
.Sp
If the RETRANSMIT parameter is provided and contains a non\-zero value, then
it is considered that we are re\-sending the request, which was already sent
previously. In this case the previous value of packet identifier is used.
.IP "recv_packet ( DETECT_BAD_ID )" 4
.IX Item "recv_packet ( DETECT_BAD_ID )"
Receives a Radius reply packet. Returns the Radius Reply type (see possible
values for \f(CW\*(C`REQUEST_TYPE\*(C'\fR in method \f(CW\*(C`send_packet\*(C'\fR) or undef on failure. Note
that failure may be due to a failed \fBrecv()\fR or a bad Radius response
authenticator. Use \f(CW\*(C`get_error\*(C'\fR to find out.
.Sp
If the DETECT_BAD_ID parameter is supplied and contains a non\-zero value, then
calculation of the packet identifier is performed before authenticator check
and EBADID error returned in case when packet identifier from the response
doesn\*(Aqt match to the request. If the DETECT_BAD_ID is not provided or contains zero value then
EBADAUTH returned in such case.
.IP "set_timeout ( TIMEOUT )" 4
.IX Item "set_timeout ( TIMEOUT )"
Sets socket I/O activity timeout. \f(CW\*(C`TIMEOUT\*(C'\fR should be specified in floating seconds
since the epoch.
.IP get_error 4
.IX Item "get_error"
Returns the last \f(CW\*(C`ERRORCODE\*(C'\fR for the current object. Errorcodes are one\-word
strings always beginning with an \*(Aq\f(CW\*(C`E\*(C'\fR\*(Aq.
.IP "strerror ( [ ERRORCODE ] )" 4
.IX Item "strerror ( [ ERRORCODE ] )"
Returns a verbose error string for the last error for the current object, or
for the specified \f(CW\*(C`ERRORCODE\*(C'\fR.
.IP error_comment 4
.IX Item "error_comment"
Returns the last error explanation for the current object. Error explanation
is generated by system call.
.IP get_active_node 4
.IX Item "get_active_node"
Returns currently active radius node in standard numbers\-and\-dots notation with
port delimited by colon.
.SH AUTHOR
.IX Header "AUTHOR"
Carl Declerck \- original design
Alexander Kapitanenko and Andrew
Zhilenko \- later modifications.
.PP
PortaOne Development Team is
the current module\*(Aqs maintainer at CPAN.