xref: /freebsd/crypto/krb5/src/include/krad.h (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * Copyright 2013 Red Hat, Inc.  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 are met:
7  *
8  *    1. Redistributions of source code must retain the above copyright
9  *       notice, this list of conditions and the following disclaimer.
10  *
11  *    2. Redistributions in binary form must reproduce the above copyright
12  *       notice, this list of conditions and the following disclaimer in
13  *       the documentation and/or other materials provided with the
14  *       distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
17  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * This API is not considered as stable as the main krb5 API.
31  *
32  * - We may make arbitrary incompatible changes between feature releases
33  *   (e.g. from 1.12 to 1.13).
34  * - We will make some effort to avoid making incompatible changes for
35  *   bugfix releases, but will make them if necessary.
36  */
37 
38 #ifndef KRAD_H_
39 #define KRAD_H_
40 
41 #include <krb5.h>
42 #include <verto.h>
43 #include <stddef.h>
44 #include <stdio.h>
45 
46 #define KRAD_PACKET_SIZE_MAX 4096
47 
48 #define KRAD_SERVICE_TYPE_LOGIN 1
49 #define KRAD_SERVICE_TYPE_FRAMED 2
50 #define KRAD_SERVICE_TYPE_CALLBACK_LOGIN 3
51 #define KRAD_SERVICE_TYPE_CALLBACK_FRAMED 4
52 #define KRAD_SERVICE_TYPE_OUTBOUND 5
53 #define KRAD_SERVICE_TYPE_ADMINISTRATIVE 6
54 #define KRAD_SERVICE_TYPE_NAS_PROMPT 7
55 #define KRAD_SERVICE_TYPE_AUTHENTICATE_ONLY 8
56 #define KRAD_SERVICE_TYPE_CALLBACK_NAS_PROMPT 9
57 #define KRAD_SERVICE_TYPE_CALL_CHECK 10
58 #define KRAD_SERVICE_TYPE_CALLBACK_ADMINISTRATIVE 11
59 
60 #define KRAD_ATTR_USER_NAME 1
61 #define KRAD_ATTR_USER_PASSWORD 2
62 #define KRAD_ATTR_SERVICE_TYPE 6
63 #define KRAD_ATTR_NAS_IDENTIFIER 32
64 #define KRAD_ATTR_PROXY_STATE 33
65 #define KRAD_ATTR_MESSAGE_AUTHENTICATOR 80
66 
67 #define KRAD_CODE_ACCESS_REQUEST 1
68 #define KRAD_CODE_ACCESS_ACCEPT 2
69 #define KRAD_CODE_ACCESS_REJECT 3
70 #define KRAD_CODE_ACCESS_CHALLENGE 11
71 
72 typedef struct krad_attrset_st krad_attrset;
73 typedef struct krad_packet_st krad_packet;
74 typedef struct krad_client_st krad_client;
75 typedef unsigned char krad_code;
76 typedef unsigned char krad_attr;
77 
78 /* Called when a response is received or the request times out. */
79 typedef void
80 (*krad_cb)(krb5_error_code retval, const krad_packet *request,
81            const krad_packet *response, void *data);
82 
83 /*
84  * Called to iterate over a set of requests.  Either the callback will be
85  * called until it returns NULL, or it will be called with cancel = TRUE to
86  * terminate in the middle of an iteration.
87  */
88 typedef const krad_packet *
89 (*krad_packet_iter_cb)(void *data, krb5_boolean cancel);
90 
91 /*
92  * Code
93  */
94 
95 /* Convert a code name to its number. Only works for codes defined
96  * by RFC 2875 or 2882. Returns 0 if the name was not found. */
97 krad_code
98 krad_code_name2num(const char *name);
99 
100 /* Convert a code number to its name. Only works for attributes defined
101  * by RFC 2865 or 2882. Returns NULL if the name was not found. */
102 const char *
103 krad_code_num2name(krad_code code);
104 
105 /*
106  * Attribute
107  */
108 
109 /* Convert an attribute name to its number. Only works for attributes defined
110  * by RFC 2865. Returns 0 if the name was not found. */
111 krad_attr
112 krad_attr_name2num(const char *name);
113 
114 /* Convert an attribute number to its name. Only works for attributes defined
115  * by RFC 2865. Returns NULL if the name was not found. */
116 const char *
117 krad_attr_num2name(krad_attr type);
118 
119 /*
120  * Attribute set
121  */
122 
123 /* Create a new attribute set. */
124 krb5_error_code
125 krad_attrset_new(krb5_context ctx, krad_attrset **set);
126 
127 /* Create a deep copy of an attribute set. */
128 krb5_error_code
129 krad_attrset_copy(const krad_attrset *set, krad_attrset **copy);
130 
131 /* Free an attribute set. */
132 void
133 krad_attrset_free(krad_attrset *set);
134 
135 /* Add an attribute to a set. */
136 krb5_error_code
137 krad_attrset_add(krad_attrset *set, krad_attr type, const krb5_data *data);
138 
139 /* Add a four-octet unsigned number attribute to the given set. */
140 krb5_error_code
141 krad_attrset_add_number(krad_attrset *set, krad_attr type, krb5_ui_4 num);
142 
143 /* Delete the specified attribute. */
144 void
145 krad_attrset_del(krad_attrset *set, krad_attr type, size_t indx);
146 
147 /* Get the specified attribute. */
148 const krb5_data *
149 krad_attrset_get(const krad_attrset *set, krad_attr type, size_t indx);
150 
151 /*
152  * Packet
153  */
154 
155 /* Determine the bytes needed from the socket to get the whole packet.  Don't
156  * cache the return value as it can change! Returns -1 on EBADMSG. */
157 ssize_t
158 krad_packet_bytes_needed(const krb5_data *buffer);
159 
160 /* Free a packet. */
161 void
162 krad_packet_free(krad_packet *pkt);
163 
164 /*
165  * Create a new request packet.
166  *
167  * This function takes the attributes specified in set and converts them into a
168  * radius packet. The packet will have a randomized id. If cb is not NULL, it
169  * will be called passing data as the argument to iterate over a set of
170  * outstanding requests. In this case, the id will be both random and unique
171  * across the set of requests.
172  */
173 krb5_error_code
174 krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
175                         const krad_attrset *set, krad_packet_iter_cb cb,
176                         void *data, krad_packet **request);
177 
178 /*
179  * Create a new response packet.
180  *
181  * This function is similar to krad_packet_new_requst() except that it crafts a
182  * packet in response to a request packet. This new packet will borrow values
183  * from the request such as the id and the authenticator.
184  */
185 krb5_error_code
186 krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
187                          const krad_attrset *set, const krad_packet *request,
188                          krad_packet **response);
189 
190 /*
191  * Decode a request radius packet from krb5_data.
192  *
193  * The resulting decoded packet will be a request packet stored in *reqpkt.
194  *
195  * If cb is NULL, *duppkt will always be NULL.
196  *
197  * If cb is not NULL, it will be called (with the data argument) to iterate
198  * over a set of requests currently being processed. In this case, if the
199  * packet is a duplicate of an already received request, the original request
200  * will be set in *duppkt.
201  */
202 krb5_error_code
203 krad_packet_decode_request(krb5_context ctx, const char *secret,
204                            const krb5_data *buffer, krad_packet_iter_cb cb,
205                            void *data, const krad_packet **duppkt,
206                            krad_packet **reqpkt);
207 
208 /*
209  * Decode a response radius packet from krb5_data.
210  *
211  * The resulting decoded packet will be a response packet stored in *rsppkt.
212  *
213  * If cb is NULL, *reqpkt will always be NULL.
214  *
215  * If cb is not NULL, it will be called (with the data argument) to iterate
216  * over a set of requests awaiting responses. In this case, if the response
217  * packet matches one of these requests, the original request will be set in
218  * *reqpkt.
219  */
220 krb5_error_code
221 krad_packet_decode_response(krb5_context ctx, const char *secret,
222                             const krb5_data *buffer, krad_packet_iter_cb cb,
223                             void *data, const krad_packet **reqpkt,
224                             krad_packet **rsppkt);
225 
226 /* Encode packet. */
227 const krb5_data *
228 krad_packet_encode(const krad_packet *pkt);
229 
230 /* Get the code for the given packet. */
231 krad_code
232 krad_packet_get_code(const krad_packet *pkt);
233 
234 /* Get the specified attribute. */
235 const krb5_data *
236 krad_packet_get_attr(const krad_packet *pkt, krad_attr type, size_t indx);
237 
238 /*
239  * Client
240  */
241 
242 /* Create a new client. */
243 krb5_error_code
244 krad_client_new(krb5_context kctx, verto_ctx *vctx, krad_client **client);
245 
246 /* Free the client. */
247 void
248 krad_client_free(krad_client *client);
249 
250 /*
251  * Send a request to a radius server.
252  *
253  * The remote host may be specified by one of the following formats:
254  *  - /path/to/unix.socket
255  *  - IPv4
256  *  - IPv4:port
257  *  - IPv4:service
258  *  - [IPv6]
259  *  - [IPv6]:port
260  *  - [IPv6]:service
261  *  - hostname
262  *  - hostname:port
263  *  - hostname:service
264  *
265  * The timeout parameter (milliseconds) is the total timeout across all remote
266  * hosts (when DNS returns multiple entries) and all retries.  For stream
267  * sockets, the retries parameter is ignored and no retries are performed.
268  *
269  * The cb function will be called with the data argument when either a response
270  * is received or the request times out on all possible remote hosts.
271  */
272 krb5_error_code
273 krad_client_send(krad_client *rc, krad_code code, const krad_attrset *attrs,
274                  const char *remote, const char *secret, int timeout,
275                  size_t retries, krad_cb cb, void *data);
276 
277 #endif /* KRAD_H_ */
278