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