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