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