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 October 30, 1999 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_init_send_request "struct rad_handle *h" "int *fd" "struct timeval *tv" 59.Ft int 60.Fn rad_put_addr "struct rad_handle *h" "int type" "struct in_addr addr" 61.Ft int 62.Fn rad_put_attr "struct rad_handle *h" "int type" "const void *data" "size_t len" 63.Ft int 64.Fn rad_put_int "struct rad_handle *h" "int type" "u_int32_t value" 65.Ft int 66.Fn rad_put_string "struct rad_handle *h" "int type" "const char *str" 67.Ft int 68.Fn rad_send_request "struct rad_handle *h" 69.Ft const char * 70.Fn rad_strerror "struct rad_handle *h" 71.Sh DESCRIPTION 72The 73.Nm 74library implements the client side of the Remote Authentication Dial 75In User Service (RADIUS). RADIUS, defined in RFCs 2138 and 2139, 76allows clients to perform authentication and accounting by means of 77network requests to remote servers. 78.Sh INITIALIZATION 79To use the library, an application must first call 80.Fn rad_auth_open 81or 82.Fn rad_acct_open 83to obtain a 84.Va struct rad_handle * , 85which provides the context for subsequent operations. 86The former function is used for RADIUS authentication and the 87latter is used for RADIUS accounting. 88Calls to 89.Fn rad_auth_open 90and 91.Fn rad_acct_open 92always succeed unless insufficient virtual memory is available. If 93the necessary memory cannot be allocated, the functions return 94.Dv NULL . 95For compatibility with earlier versions of this library, 96.Fn rad_open 97is provided as a synonym for 98.Fn rad_auth_open . 99.Pp 100Before issuing any RADIUS requests, the library must be made aware 101of the servers it can contact. The easiest way to configure the 102library is to call 103.Fn rad_config . 104.Fn rad_config 105causes the library to read a configuration file whose format is 106described in 107.Xr radius.conf 5 . 108The pathname of the configuration file is passed as the 109.Va file 110argument to 111.Fn rad_config . 112This argument may also be given as 113.Dv NULL , 114in which case the standard configuration file 115.Pa /etc/radius.conf 116is used. 117.Fn rad_config 118returns 0 on success, or -1 if an error occurs. 119.Pp 120The library can also be configured programmatically by calls to 121.Fn rad_add_server . 122The 123.Va host 124parameter specifies the server host, either as a fully qualified 125domain name or as a dotted-quad IP address in text form. 126The 127.Va port 128parameter specifies the UDP port to contact on the server. If 129.Va port 130is given as 0, the library looks up the 131.Ql radius/udp 132or 133.Ql radacct/udp 134service in the network services database, and uses the port found 135there. If no entry is found, the library uses the standard RADIUS 136ports, 1812 for authentication and 1813 for accounting. 137The shared secret for the server host is passed to the 138.Va secret 139parameter. 140It may be any NUL-terminated string of bytes. The RADIUS protocol 141ignores all but the leading 128 bytes of the shared secret. 142The timeout for receiving replies from the server is passed to the 143.Va timeout 144parameter, in units of seconds. The maximum number of repeated 145requests to make before giving up is passed into the 146.Va max_tries 147parameter. 148.Fn rad_add_server 149returns 0 on success, or -1 if an error occurs. 150.Pp 151.Fn rad_add_server 152may be called multiple times, and it may be used together with 153.Fn rad_config . 154At most 10 servers may be specified. 155When multiple servers are given, they are tried in round-robin 156fashion until a valid response is received, or until each server's 157.Va max_tries 158limit has been reached. 159.Sh CREATING A RADIUS REQUEST 160A RADIUS request consists of a code specifying the kind of request, 161and zero or more attributes which provide additional information. To 162begin constructing a new request, call 163.Fn rad_create_request . 164In addition to the usual 165.Va struct rad_handle * , 166this function takes a 167.Va code 168parameter which specifies the type of the request. Most often this 169will be 170.Dv RAD_ACCESS_REQUEST . 171.Fn rad_create_request 172returns 0 on success, or -1 on if an error occurs. 173.Pp 174After the request has been created with 175.Fn rad_create_request , 176attributes can be attached to it. This is done through calls to 177.Fn rad_put_addr , 178.Fn rad_put_int , 179and 180.Fn rad_put_string . 181Each accepts a 182.Va type 183parameter identifying the attribute, and a value which may be 184an Internet address, an integer, or a NUL-terminated string, 185respectively. 186.Pp 187The library also provides a function 188.Fn rad_put_attr 189which can be used to supply a raw, uninterpreted attribute. The 190.Va data 191argument points to an array of bytes, and the 192.Va len 193argument specifies its length. 194.Pp 195The 196.Fn rad_put_X 197functions return 0 on success, or -1 if an error occurs. 198.Sh SENDING THE REQUEST AND RECEIVING THE RESPONSE 199After the RADIUS request has been constructed, it is sent either by means of 200.Fn rad_send_request 201or by a combination of calls to 202.Fn rad_init_send_request 203and 204.Fn rad_continue_send_request . 205.Pp 206The 207.Fn rad_send_request 208function sends the request and waits for a valid reply, 209retrying the defined servers in round-robin fashion as necessary. 210If a valid response is received, 211.Fn rad_send_request 212returns the RADIUS code which specifies the type of the response. 213This will typically be 214.Dv RAD_ACCESS_ACCEPT , 215.Dv RAD_ACCESS_REJECT , 216or 217.Dv RAD_ACCESS_CHALLENGE . 218If no valid response is received, 219.Fn rad_send_request 220returns -1. 221.Pp 222As an alternative, if you do not wish to block waiting for a response, 223.Fn rad_init_send_request 224and 225.Fn rad_continue_send_request 226may be used instead. If a reply is received from the RADIUS server or a 227timeout occurs, these functions return a value as described for 228.Fn rad_send_request . 229Otherwise, a value of zero is returned and the values pointed to by 230.Ar fd 231and 232.Ar tv 233are set to the descriptor and timeout that should be passed to 234.Xr select 2 . 235.Pp 236.Fn rad_init_send_request 237must be called first, followed by repeated calls to 238.Fn rad_continue_send_request 239as long as a return value of zero is given. 240Between each call, the application should call 241.Xr select 2 , 242passing 243.Ar *fd 244as a read descriptor and timing out after the interval specified by 245.Ar tv . 246When select returns, 247.Fn rad_continue_send_request 248should be called with 249.Ar selected 250set to a non-zero value if 251.Xr select 2 252indicated that the descriptor is readable. 253.Pp 254Like RADIUS requests, each response may contain zero or more 255attributes. After a response has been received successfully by 256.Fn rad_send_request 257or 258.Fn rad_continue_send_request , 259its attributes can be extracted one by one using 260.Fn rad_get_attr . 261Each time 262.Fn rad_get_attr 263is called, it gets the next attribute from the current response, and 264stores a pointer to the data and the length of the data via the 265reference parameters 266.Va data 267and 268.Va len , 269respectively. Note that the data resides in the response itself, 270and must not be modified. 271A successful call to 272.Fn rad_get_attr 273returns the RADIUS attribute type. 274If no more attributes remain in the current response, 275.Fn rad_get_attr 276returns 0. 277If an error such as a malformed attribute is detected, -1 is 278returned. 279.Pp 280The common types of attributes can be decoded using 281.Fn rad_cvt_addr , 282.Fn rad_cvt_int , 283and 284.Fn rad_cvt_string . 285These functions accept a pointer to the attribute data, which should 286have been obtained using 287.Fn rad_get_attr . 288In the case of 289.Fn rad_cvt_string , 290the length 291.Va len 292must also be given. These functions interpret the attribute as an 293Internet address, an integer, or a string, respectively, and return 294its value. 295.Fn rad_cvt_string 296returns its value as a NUL-terminated string in dynamically 297allocated memory. The application should free the string using 298.Xr free 3 299when it is no longer needed. 300.Pp 301If insufficient virtual memory is available, 302.Fn rad_cvt_string 303returns 304.Dv NULL . 305.Fn rad_cvt_addr 306and 307.Fn rad_cvt_int 308cannot fail. 309.Sh OBTAINING ERROR MESSAGES 310Those functions which accept a 311.Va struct rad_handle * 312argument record an error message if they fail. The error message 313can be retrieved by calling 314.Fn rad_strerror . 315The message text is overwritten on each new error for the given 316.Va struct rad_handle * . 317Thus the message must be copied if it is to be preserved through 318subsequent library calls using the same handle. 319.Sh CLEANUP 320To free the resources used by the RADIUS library, call 321.Fn rad_close . 322.Sh RETURN VALUES 323The following functions return a non-negative value on success. If 324they detect an error, they return -1 and record an error message 325which can be retrieved using 326.Fn rad_strerror . 327.Pp 328.Bl -item -offset indent -compact 329.It 330.Fn rad_add_server 331.It 332.Fn rad_config 333.It 334.Fn rad_create_request 335.It 336.Fn rad_get_attr 337.It 338.Fn rad_put_addr 339.It 340.Fn rad_put_attr 341.It 342.Fn rad_put_int 343.It 344.Fn rad_put_string 345.It 346.Fn rad_init_send_request 347.It 348.Fn rad_continue_send_request 349.It 350.Fn rad_send_request 351.El 352.Pp 353The following functions return a 354.No non- Ns Dv NULL 355pointer on success. If they are unable to allocate sufficient 356virtual memory, they return 357.Dv NULL , 358without recording an error message. 359.Pp 360.Bl -item -offset indent -compact 361.It 362.Fn rad_acct_open 363.It 364.Fn rad_auth_open 365.It 366.Fn rad_cvt_string 367.El 368.Sh FILES 369.Pa /etc/radius.conf 370.Sh SEE ALSO 371.Xr radius.conf 5 372.Rs 373.%A C. Rigney, et al 374.%T "Remote Authentication Dial In User Service (RADIUS)" 375.%O RFC 2138 376.Re 377.Rs 378.%A C. Rigney 379.%T RADIUS Accounting 380.%O RFC 2139 381.Re 382.Sh AUTHORS 383This software was originally written by 384.An John Polstra , 385and donated to the 386.Fx 387project by Juniper Networks, Inc. 388Oleg Semyonov subsequently added the ability to perform RADIUS 389accounting. 390