1.\" Copyright 1998 Juniper Networks, Inc. 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23.\" SUCH DAMAGE. 24.\" 25.\" $FreeBSD$ 26.\" 27.Dd June 12, 2002 28.Dt LIBRADIUS 3 29.Os 30.Sh NAME 31.Nm libradius 32.Nd RADIUS client library 33.Sh SYNOPSIS 34.In radlib.h 35.Ft "struct rad_handle *" 36.Fn rad_acct_open "void" 37.Ft int 38.Fn rad_add_server "struct rad_handle *h" "const char *host" "int port" "const char *secret" "int timeout" "int max_tries" 39.Ft "struct rad_handle *" 40.Fn rad_auth_open "void" 41.Ft void 42.Fn rad_close "struct rad_handle *h" 43.Ft int 44.Fn rad_config "struct rad_handle *h" "const char *file" 45.Ft int 46.Fn rad_continue_send_request "struct rad_handle *h" "int selected" "int *fd" "struct timeval *tv" 47.Ft int 48.Fn rad_create_request "struct rad_handle *h" "int code" 49.Ft "struct in_addr" 50.Fn rad_cvt_addr "const void *data" 51.Ft u_int32_t 52.Fn rad_cvt_int "const void *data" 53.Ft char * 54.Fn rad_cvt_string "const void *data" "size_t len" 55.Ft int 56.Fn rad_get_attr "struct rad_handle *h" "const void **data" "size_t *len" 57.Ft int 58.Fn rad_get_vendor_attr "u_int32_t *vendor" "const void **data" "size_t *len" 59.Ft int 60.Fn rad_init_send_request "struct rad_handle *h" "int *fd" "struct timeval *tv" 61.Ft int 62.Fn rad_put_addr "struct rad_handle *h" "int type" "struct in_addr addr" 63.Ft int 64.Fn rad_put_attr "struct rad_handle *h" "int type" "const void *data" "size_t len" 65.Ft int 66.Fn rad_put_int "struct rad_handle *h" "int type" "u_int32_t value" 67.Ft int 68.Fn rad_put_string "struct rad_handle *h" "int type" "const char *str" 69.Ft int 70.Fn rad_put_vendor_addr "struct rad_handle *h" "int vendor" "int type" "struct in_addr addr" 71.Ft int 72.Fn rad_put_vendor_attr "struct rad_handle *h" "int vendor" "int type" "const void *data" "size_t len" 73.Ft int 74.Fn rad_put_vendor_int "struct rad_handle *h" "int vendor" "int type" "u_int32_t value" 75.Ft int 76.Fn rad_put_vendor_string "struct rad_handle *h" "int vendor" "int type" "const char *str" 77.Ft ssize_t 78.Fn rad_request_authenticator "struct rad_handle *h" "char *buf" "size_t len" 79.Ft int 80.Fn rad_send_request "struct rad_handle *h" 81.Ft "const char *" 82.Fn rad_server_secret "struct rad_handle *h" 83.Ft "const char *" 84.Fn rad_strerror "struct rad_handle *h" 85.Sh DESCRIPTION 86The 87.Nm 88library implements the client side of the Remote Authentication Dial 89In User Service (RADIUS). 90RADIUS, defined in RFCs 2138 and 2139, 91allows clients to perform authentication and accounting by means of 92network requests to remote servers. 93.Ss Initialization 94To use the library, an application must first call 95.Fn rad_auth_open 96or 97.Fn rad_acct_open 98to obtain a 99.Vt "struct rad_handle *" , 100which provides the context for subsequent operations. 101The former function is used for RADIUS authentication and the 102latter is used for RADIUS accounting. 103Calls to 104.Fn rad_auth_open 105and 106.Fn rad_acct_open 107always succeed unless insufficient virtual memory is available. 108If 109the necessary memory cannot be allocated, the functions return 110.Dv NULL . 111For compatibility with earlier versions of this library, 112.Fn rad_open 113is provided as a synonym for 114.Fn rad_auth_open . 115.Pp 116Before issuing any RADIUS requests, the library must be made aware 117of the servers it can contact. 118The easiest way to configure the 119library is to call 120.Fn rad_config . 121.Fn rad_config 122causes the library to read a configuration file whose format is 123described in 124.Xr radius.conf 5 . 125The pathname of the configuration file is passed as the 126.Fa file 127argument to 128.Fn rad_config . 129This argument may also be given as 130.Dv NULL , 131in which case the standard configuration file 132.Pa /etc/radius.conf 133is used. 134.Fn rad_config 135returns 0 on success, or \-1 if an error occurs. 136.Pp 137The library can also be configured programmatically by calls to 138.Fn rad_add_server . 139The 140.Fa host 141parameter specifies the server host, either as a fully qualified 142domain name or as a dotted-quad IP address in text form. 143The 144.Fa port 145parameter specifies the UDP port to contact on the server. 146If 147.Fa port 148is given as 0, the library looks up the 149.Ql radius/udp 150or 151.Ql radacct/udp 152service in the network 153.Xr services 5 154database, and uses the port found 155there. 156If no entry is found, the library uses the standard RADIUS 157ports, 1812 for authentication and 1813 for accounting. 158The shared secret for the server host is passed to the 159.Fa secret 160parameter. 161It may be any 162.Dv NUL Ns -terminated 163string of bytes. 164The RADIUS protocol 165ignores all but the leading 128 bytes of the shared secret. 166The timeout for receiving replies from the server is passed to the 167.Fa timeout 168parameter, in units of seconds. 169The maximum number of repeated 170requests to make before giving up is passed into the 171.Fa max_tries 172parameter. 173.Fn rad_add_server 174returns 0 on success, or \-1 if an error occurs. 175.Pp 176.Fn rad_add_server 177may be called multiple times, and it may be used together with 178.Fn rad_config . 179At most 10 servers may be specified. 180When multiple servers are given, they are tried in round-robin 181fashion until a valid response is received, or until each server's 182.Fa max_tries 183limit has been reached. 184.Ss Creating a RADIUS Request 185A RADIUS request consists of a code specifying the kind of request, 186and zero or more attributes which provide additional information. 187To 188begin constructing a new request, call 189.Fn rad_create_request . 190In addition to the usual 191.Vt "struct rad_handle *" , 192this function takes a 193.Fa code 194parameter which specifies the type of the request. 195Most often this 196will be 197.Dv RAD_ACCESS_REQUEST . 198.Fn rad_create_request 199returns 0 on success, or \-1 on if an error occurs. 200.Pp 201After the request has been created with 202.Fn rad_create_request , 203attributes can be attached to it. 204This is done through calls to 205.Fn rad_put_addr , 206.Fn rad_put_int , 207and 208.Fn rad_put_string . 209Each accepts a 210.Fa type 211parameter identifying the attribute, and a value which may be 212an Internet address, an integer, or a 213.Dv NUL Ns -terminated 214string, 215respectively. 216Alternatively, 217.Fn rad_put_vendor_addr , 218.Fn rad_put_vendor_int 219or 220.Fn rad_put_vendor_string 221may be used to specify vendor specific attributes. 222Vendor specific 223definitions may be found in 224.In radlib_vs.h 225.Pp 226The library also provides a function 227.Fn rad_put_attr 228which can be used to supply a raw, uninterpreted attribute. 229The 230.Fa data 231argument points to an array of bytes, and the 232.Fa len 233argument specifies its length. 234.Pp 235The 236.Fn rad_put_X 237functions return 0 on success, or \-1 if an error occurs. 238.Ss Sending the Request and Receiving the Response 239After the RADIUS request has been constructed, it is sent either by means of 240.Fn rad_send_request 241or by a combination of calls to 242.Fn rad_init_send_request 243and 244.Fn rad_continue_send_request . 245.Pp 246The 247.Fn rad_send_request 248function sends the request and waits for a valid reply, 249retrying the defined servers in round-robin fashion as necessary. 250If a valid response is received, 251.Fn rad_send_request 252returns the RADIUS code which specifies the type of the response. 253This will typically be 254.Dv RAD_ACCESS_ACCEPT , 255.Dv RAD_ACCESS_REJECT , 256or 257.Dv RAD_ACCESS_CHALLENGE . 258If no valid response is received, 259.Fn rad_send_request 260returns \-1. 261.Pp 262As an alternative, if you do not wish to block waiting for a response, 263.Fn rad_init_send_request 264and 265.Fn rad_continue_send_request 266may be used instead. 267If a reply is received from the RADIUS server or a 268timeout occurs, these functions return a value as described for 269.Fn rad_send_request . 270Otherwise, a value of zero is returned and the values pointed to by 271.Fa fd 272and 273.Fa tv 274are set to the descriptor and timeout that should be passed to 275.Xr select 2 . 276.Pp 277.Fn rad_init_send_request 278must be called first, followed by repeated calls to 279.Fn rad_continue_send_request 280as long as a return value of zero is given. 281Between each call, the application should call 282.Xr select 2 , 283passing 284.Fa *fd 285as a read descriptor and timing out after the interval specified by 286.Fa tv . 287When 288.Xr select 2 289returns, 290.Fn rad_continue_send_request 291should be called with 292.Fa selected 293set to a non-zero value if 294.Xr select 2 295indicated that the descriptor is readable. 296.Pp 297Like RADIUS requests, each response may contain zero or more 298attributes. 299After a response has been received successfully by 300.Fn rad_send_request 301or 302.Fn rad_continue_send_request , 303its attributes can be extracted one by one using 304.Fn rad_get_attr . 305Each time 306.Fn rad_get_attr 307is called, it gets the next attribute from the current response, and 308stores a pointer to the data and the length of the data via the 309reference parameters 310.Fa data 311and 312.Fa len , 313respectively. 314Note that the data resides in the response itself, 315and must not be modified. 316A successful call to 317.Fn rad_get_attr 318returns the RADIUS attribute type. 319If no more attributes remain in the current response, 320.Fn rad_get_attr 321returns 0. 322If an error such as a malformed attribute is detected, \-1 is 323returned. 324.Pp 325If 326.Fn rad_get_attr 327returns 328.Dv RAD_VENDOR_SPECIFIC , 329.Fn rad_get_vendor_attr 330may be called to determine the vendor. 331The vendor specific RADIUS attribute type is returned. 332The reference parameters 333.Fa data 334and 335.Fa len 336(as returned from 337.Fn rad_get_attr ) 338are passed to 339.Fn rad_get_vendor_attr , 340and are adjusted to point to the vendor specific attribute data. 341.Pp 342The common types of attributes can be decoded using 343.Fn rad_cvt_addr , 344.Fn rad_cvt_int , 345and 346.Fn rad_cvt_string . 347These functions accept a pointer to the attribute data, which should 348have been obtained using 349.Fn rad_get_attr 350and optionally 351.Fn rad_get_vendor_attr . 352In the case of 353.Fn rad_cvt_string , 354the length 355.Fa len 356must also be given. 357These functions interpret the attribute as an 358Internet address, an integer, or a string, respectively, and return 359its value. 360.Fn rad_cvt_string 361returns its value as a 362.Dv NUL Ns -terminated 363string in dynamically 364allocated memory. 365The application should free the string using 366.Xr free 3 367when it is no longer needed. 368.Pp 369If insufficient virtual memory is available, 370.Fn rad_cvt_string 371returns 372.Dv NULL . 373.Fn rad_cvt_addr 374and 375.Fn rad_cvt_int 376cannot fail. 377.Pp 378The 379.Fn rad_request_authenticator 380function may be used to obtain the Request-Authenticator attribute value 381associated with the current RADIUS server according to the supplied 382rad_handle. 383The target buffer 384.Fa buf 385of length 386.Fa len 387must be supplied and should be at least 16 bytes. 388The return value is the number of bytes written to 389.Fa buf 390or \-1 to indicate that 391.Fa len 392was not large enough. 393.Pp 394The 395.Fn rad_server_secret 396returns the secret shared with the current RADIUS server according to the 397supplied rad_handle. 398.Ss Obtaining Error Messages 399Those functions which accept a 400.Vt "struct rad_handle *" 401argument record an error message if they fail. 402The error message 403can be retrieved by calling 404.Fn rad_strerror . 405The message text is overwritten on each new error for the given 406.Vt "struct rad_handle *" . 407Thus the message must be copied if it is to be preserved through 408subsequent library calls using the same handle. 409.Ss Cleanup 410To free the resources used by the RADIUS library, call 411.Fn rad_close . 412.Sh RETURN VALUES 413The following functions return a non-negative value on success. 414If 415they detect an error, they return \-1 and record an error message 416which can be retrieved using 417.Fn rad_strerror . 418.Pp 419.Bl -item -offset indent -compact 420.It 421.Fn rad_add_server 422.It 423.Fn rad_config 424.It 425.Fn rad_create_request 426.It 427.Fn rad_get_attr 428.It 429.Fn rad_put_addr 430.It 431.Fn rad_put_attr 432.It 433.Fn rad_put_int 434.It 435.Fn rad_put_string 436.It 437.Fn rad_init_send_request 438.It 439.Fn rad_continue_send_request 440.It 441.Fn rad_send_request 442.El 443.Pp 444The following functions return a 445.No non- Ns Dv NULL 446pointer on success. 447If they are unable to allocate sufficient 448virtual memory, they return 449.Dv NULL , 450without recording an error message. 451.Pp 452.Bl -item -offset indent -compact 453.It 454.Fn rad_acct_open 455.It 456.Fn rad_auth_open 457.It 458.Fn rad_cvt_string 459.El 460.Sh FILES 461.Bl -tag -width indent 462.It Pa /etc/radius.conf 463.El 464.Sh SEE ALSO 465.Xr radius.conf 5 466.Rs 467.%A "C. Rigney, et al" 468.%T "Remote Authentication Dial In User Service (RADIUS)" 469.%O "RFC 2138" 470.Re 471.Rs 472.%A "C. Rigney" 473.%T "RADIUS Accounting" 474.%O "RFC 2139" 475.Re 476.Sh AUTHORS 477.An -nosplit 478This software was originally written by 479.An John Polstra , 480and donated to the 481.Fx 482project by Juniper Networks, Inc. 483.An Oleg Semyonov 484subsequently added the ability to perform RADIUS 485accounting. 486