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