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