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 April 27, 2004 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_message_authentic "struct rad_handle *h" 71.Ft int 72.Fn rad_put_vendor_addr "struct rad_handle *h" "int vendor" "int type" "struct in_addr addr" 73.Ft int 74.Fn rad_put_vendor_attr "struct rad_handle *h" "int vendor" "int type" "const void *data" "size_t len" 75.Ft int 76.Fn rad_put_vendor_int "struct rad_handle *h" "int vendor" "int type" "u_int32_t value" 77.Ft int 78.Fn rad_put_vendor_string "struct rad_handle *h" "int vendor" "int type" "const char *str" 79.Ft ssize_t 80.Fn rad_request_authenticator "struct rad_handle *h" "char *buf" "size_t len" 81.Ft int 82.Fn rad_send_request "struct rad_handle *h" 83.Ft "const char *" 84.Fn rad_server_secret "struct rad_handle *h" 85.Ft u_char * 86.Fn rad_demangle "struct rad_handle *h" "const void *mangled" "size_t mlen" 87.Ft u_char * 88.Fn rad_demangle_mppe_key "struct rad_handle *h" "const void *mangled" "size_t mlen" "size_t *len" 89.Ft "const char *" 90.Fn rad_strerror "struct rad_handle *h" 91.Sh DESCRIPTION 92The 93.Nm 94library implements the client side of the Remote Authentication Dial 95In User Service (RADIUS). 96RADIUS, defined in RFCs 2865 and 2866, 97allows clients to perform authentication and accounting by means of 98network requests to remote servers. 99.Ss Initialization 100To use the library, an application must first call 101.Fn rad_auth_open 102or 103.Fn rad_acct_open 104to obtain a 105.Vt "struct rad_handle *" , 106which provides the context for subsequent operations. 107The former function is used for RADIUS authentication and the 108latter is used for RADIUS accounting. 109Calls to 110.Fn rad_auth_open 111and 112.Fn rad_acct_open 113always succeed unless insufficient virtual memory is available. 114If 115the necessary memory cannot be allocated, the functions return 116.Dv NULL . 117For compatibility with earlier versions of this library, 118.Fn rad_open 119is provided as a synonym for 120.Fn rad_auth_open . 121.Pp 122Before issuing any RADIUS requests, the library must be made aware 123of the servers it can contact. 124The easiest way to configure the 125library is to call 126.Fn rad_config . 127.Fn rad_config 128causes the library to read a configuration file whose format is 129described in 130.Xr radius.conf 5 . 131The pathname of the configuration file is passed as the 132.Fa file 133argument to 134.Fn rad_config . 135This argument may also be given as 136.Dv NULL , 137in which case the standard configuration file 138.Pa /etc/radius.conf 139is used. 140.Fn rad_config 141returns 0 on success, or \-1 if an error occurs. 142.Pp 143The library can also be configured programmatically by calls to 144.Fn rad_add_server . 145The 146.Fa host 147parameter specifies the server host, either as a fully qualified 148domain name or as a dotted-quad IP address in text form. 149The 150.Fa port 151parameter specifies the UDP port to contact on the server. 152If 153.Fa port 154is given as 0, the library looks up the 155.Ql radius/udp 156or 157.Ql radacct/udp 158service in the network 159.Xr services 5 160database, and uses the port found 161there. 162If no entry is found, the library uses the standard RADIUS 163ports, 1812 for authentication and 1813 for accounting. 164The shared secret for the server host is passed to the 165.Fa secret 166parameter. 167It may be any 168.Dv NUL Ns -terminated 169string of bytes. 170The RADIUS protocol 171ignores all but the leading 128 bytes of the shared secret. 172The timeout for receiving replies from the server is passed to the 173.Fa timeout 174parameter, in units of seconds. 175The maximum number of repeated 176requests to make before giving up is passed into the 177.Fa max_tries 178parameter. 179.Fn rad_add_server 180returns 0 on success, or \-1 if an error occurs. 181.Pp 182.Fn rad_add_server 183may be called multiple times, and it may be used together with 184.Fn rad_config . 185At most 10 servers may be specified. 186When multiple servers are given, they are tried in round-robin 187fashion until a valid response is received, or until each server's 188.Fa max_tries 189limit has been reached. 190.Ss Creating a RADIUS Request 191A RADIUS request consists of a code specifying the kind of request, 192and zero or more attributes which provide additional information. 193To 194begin constructing a new request, call 195.Fn rad_create_request . 196In addition to the usual 197.Vt "struct rad_handle *" , 198this function takes a 199.Fa code 200parameter which specifies the type of the request. 201Most often this 202will be 203.Dv RAD_ACCESS_REQUEST . 204.Fn rad_create_request 205returns 0 on success, or \-1 on if an error occurs. 206.Pp 207After the request has been created with 208.Fn rad_create_request , 209attributes can be attached to it. 210This is done through calls to 211.Fn rad_put_addr , 212.Fn rad_put_int , 213and 214.Fn rad_put_string . 215Each accepts a 216.Fa type 217parameter identifying the attribute, and a value which may be 218an Internet address, an integer, or a 219.Dv NUL Ns -terminated 220string, 221respectively. 222Alternatively, 223.Fn rad_put_vendor_addr , 224.Fn rad_put_vendor_int 225or 226.Fn rad_put_vendor_string 227may be used to specify vendor specific attributes. 228Vendor specific 229definitions may be found in 230.In radlib_vs.h 231.Pp 232The library also provides a function 233.Fn rad_put_attr 234which can be used to supply a raw, uninterpreted attribute. 235The 236.Fa data 237argument points to an array of bytes, and the 238.Fa len 239argument specifies its length. 240.Pp 241It is possible adding the Message-Authenticator to the request. 242This is an HMAC-MD5 hash of the entire Access-Request packet (see RFC 3579). 243This attribute must be present in any packet that includes an EAP-Message 244attribute. 245It can be added by using the 246.Fn rad_put_message_authentic 247function. 248The 249.Nm 250library 251calculates the HMAC-MD5 hash implicitly before sending the request. 252If the Message-Authenticator was found inside the response packet, 253then the packet is silently dropped, if the validation failed. 254In order to get this feature, the library should be compiled with 255OpenSSL support. 256.Pp 257The 258.Fn rad_put_X 259functions return 0 on success, or \-1 if an error occurs. 260.Ss Sending the Request and Receiving the Response 261After the RADIUS request has been constructed, it is sent either by means of 262.Fn rad_send_request 263or by a combination of calls to 264.Fn rad_init_send_request 265and 266.Fn rad_continue_send_request . 267.Pp 268The 269.Fn rad_send_request 270function sends the request and waits for a valid reply, 271retrying the defined servers in round-robin fashion as necessary. 272If a valid response is received, 273.Fn rad_send_request 274returns the RADIUS code which specifies the type of the response. 275This will typically be 276.Dv RAD_ACCESS_ACCEPT , 277.Dv RAD_ACCESS_REJECT , 278or 279.Dv RAD_ACCESS_CHALLENGE . 280If no valid response is received, 281.Fn rad_send_request 282returns \-1. 283.Pp 284As an alternative, if you do not wish to block waiting for a response, 285.Fn rad_init_send_request 286and 287.Fn rad_continue_send_request 288may be used instead. 289If a reply is received from the RADIUS server or a 290timeout occurs, these functions return a value as described for 291.Fn rad_send_request . 292Otherwise, a value of zero is returned and the values pointed to by 293.Fa fd 294and 295.Fa tv 296are set to the descriptor and timeout that should be passed to 297.Xr select 2 . 298.Pp 299.Fn rad_init_send_request 300must be called first, followed by repeated calls to 301.Fn rad_continue_send_request 302as long as a return value of zero is given. 303Between each call, the application should call 304.Xr select 2 , 305passing 306.Fa *fd 307as a read descriptor and timing out after the interval specified by 308.Fa tv . 309When 310.Xr select 2 311returns, 312.Fn rad_continue_send_request 313should be called with 314.Fa selected 315set to a non-zero value if 316.Xr select 2 317indicated that the descriptor is readable. 318.Pp 319Like RADIUS requests, each response may contain zero or more 320attributes. 321After a response has been received successfully by 322.Fn rad_send_request 323or 324.Fn rad_continue_send_request , 325its attributes can be extracted one by one using 326.Fn rad_get_attr . 327Each time 328.Fn rad_get_attr 329is called, it gets the next attribute from the current response, and 330stores a pointer to the data and the length of the data via the 331reference parameters 332.Fa data 333and 334.Fa len , 335respectively. 336Note that the data resides in the response itself, 337and must not be modified. 338A successful call to 339.Fn rad_get_attr 340returns the RADIUS attribute type. 341If no more attributes remain in the current response, 342.Fn rad_get_attr 343returns 0. 344If an error such as a malformed attribute is detected, \-1 is 345returned. 346.Pp 347If 348.Fn rad_get_attr 349returns 350.Dv RAD_VENDOR_SPECIFIC , 351.Fn rad_get_vendor_attr 352may be called to determine the vendor. 353The vendor specific RADIUS attribute type is returned. 354The reference parameters 355.Fa data 356and 357.Fa len 358(as returned from 359.Fn rad_get_attr ) 360are passed to 361.Fn rad_get_vendor_attr , 362and are adjusted to point to the vendor specific attribute data. 363.Pp 364The common types of attributes can be decoded using 365.Fn rad_cvt_addr , 366.Fn rad_cvt_int , 367and 368.Fn rad_cvt_string . 369These functions accept a pointer to the attribute data, which should 370have been obtained using 371.Fn rad_get_attr 372and optionally 373.Fn rad_get_vendor_attr . 374In the case of 375.Fn rad_cvt_string , 376the length 377.Fa len 378must also be given. 379These functions interpret the attribute as an 380Internet address, an integer, or a string, respectively, and return 381its value. 382.Fn rad_cvt_string 383returns its value as a 384.Dv NUL Ns -terminated 385string in dynamically 386allocated memory. 387The application should free the string using 388.Xr free 3 389when it is no longer needed. 390.Pp 391If insufficient virtual memory is available, 392.Fn rad_cvt_string 393returns 394.Dv NULL . 395.Fn rad_cvt_addr 396and 397.Fn rad_cvt_int 398cannot fail. 399.Pp 400The 401.Fn rad_request_authenticator 402function may be used to obtain the Request-Authenticator attribute value 403associated with the current RADIUS server according to the supplied 404rad_handle. 405The target buffer 406.Fa buf 407of length 408.Fa len 409must be supplied and should be at least 16 bytes. 410The return value is the number of bytes written to 411.Fa buf 412or \-1 to indicate that 413.Fa len 414was not large enough. 415.Pp 416The 417.Fn rad_server_secret 418returns the secret shared with the current RADIUS server according to the 419supplied rad_handle. 420.Pp 421The 422.Fn rad_demangle 423function demangles attributes containing passwords and MS-CHAPv1 MPPE-Keys. 424The return value is 425.Dv NULL 426on failure, or the plaintext attribute. 427This value should be freed using 428.Xr free 3 429when it is no longer needed. 430.Pp 431The 432.Fn rad_demangle_mppe_key 433function demangles the send- and recv-keys when using MPPE (see RFC 2548). 434The return value is 435.Dv NULL 436on failure, or the plaintext attribute. 437This value should be freed using 438.Xr free 3 439when it is no longer needed. 440.Ss Obtaining Error Messages 441Those functions which accept a 442.Vt "struct rad_handle *" 443argument record an error message if they fail. 444The error message 445can be retrieved by calling 446.Fn rad_strerror . 447The message text is overwritten on each new error for the given 448.Vt "struct rad_handle *" . 449Thus the message must be copied if it is to be preserved through 450subsequent library calls using the same handle. 451.Ss Cleanup 452To free the resources used by the RADIUS library, call 453.Fn rad_close . 454.Sh RETURN VALUES 455The following functions return a non-negative value on success. 456If 457they detect an error, they return \-1 and record an error message 458which can be retrieved using 459.Fn rad_strerror . 460.Pp 461.Bl -item -offset indent -compact 462.It 463.Fn rad_add_server 464.It 465.Fn rad_config 466.It 467.Fn rad_create_request 468.It 469.Fn rad_get_attr 470.It 471.Fn rad_put_addr 472.It 473.Fn rad_put_attr 474.It 475.Fn rad_put_int 476.It 477.Fn rad_put_string 478.It 479.Fn rad_put_message_authentic 480.It 481.Fn rad_init_send_request 482.It 483.Fn rad_continue_send_request 484.It 485.Fn rad_send_request 486.El 487.Pp 488The following functions return a 489.No non- Ns Dv NULL 490pointer on success. 491If they are unable to allocate sufficient 492virtual memory, they return 493.Dv NULL , 494without recording an error message. 495.Pp 496.Bl -item -offset indent -compact 497.It 498.Fn rad_acct_open 499.It 500.Fn rad_auth_open 501.It 502.Fn rad_cvt_string 503.El 504.Pp 505The following functions return a 506.No non- Ns Dv NULL 507pointer on success. 508If they fail, they return 509.Dv NULL , 510with recording an error message. 511.Pp 512.Bl -item -offset indent -compact 513.It 514.Fn rad_demangle 515.It 516.Fn rad_demangle_mppe_key 517.El 518.Sh FILES 519.Bl -tag -width indent 520.It Pa /etc/radius.conf 521.El 522.Sh SEE ALSO 523.Xr radius.conf 5 524.Rs 525.%A "C. Rigney, et al" 526.%T "Remote Authentication Dial In User Service (RADIUS)" 527.%O "RFC 2865" 528.Re 529.Rs 530.%A "C. Rigney" 531.%T "RADIUS Accounting" 532.%O "RFC 2866" 533.Re 534.Rs 535.%A G. Zorn 536.%T "Microsoft Vendor-specific RADIUS attributes" 537.%O RFC 2548 538.Re 539.Rs 540.%A C. Rigney, et al 541.%T "RADIUS extensions" 542.%O RFC 2869 543.Re 544.Sh AUTHORS 545.An -nosplit 546This software was originally written by 547.An John Polstra , 548and donated to the 549.Fx 550project by Juniper Networks, Inc. 551.An Oleg Semyonov 552subsequently added the ability to perform RADIUS 553accounting. 554Later additions and changes by 555.An Michael Bretterklieber . 556