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