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