The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
base.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: ca01f5208cfdfb0c0b04fbda24d75370a9d9a29e $
19 * @file src/process/tls/base.c
20 * @brief TLS processing.
21 *
22 * @copyright 2021 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
23 */
24#include <freeradius-devel/unlang/interpret.h>
25#include <freeradius-devel/util/debug.h>
26#include <freeradius-devel/protocol/tls/freeradius.h>
27
28static fr_dict_t const *dict_tls;
29
35
37
43
62
66
67#define FR_TLS_PACKET_CODE_VALID(_code) (((_code) > 0) && ((_code) <= FR_PACKET_TYPE_VALUE_NOTFOUND))
68
69#define PROCESS_INST process_tls_t
70#define PROCESS_PACKET_TYPE uint32_t
71#define PROCESS_CODE_DO_NOT_RESPOND FR_PACKET_TYPE_VALUE_FAILURE
72#define PROCESS_PACKET_CODE_VALID FR_TLS_PACKET_CODE_VALID
73
74#include <freeradius-devel/server/process.h>
75
76static int mod_instantiate(module_inst_ctx_t const *mctx)
77{
79 CONF_SECTION *server_cs = cf_item_to_section(cf_parent(mctx->mi->conf));
80
81 /*
82 * We have to define both load and save.
83 */
84 if (inst->sections.load_session && !inst->sections.store_session) {
85 cf_log_err(server_cs, "Virtual server defines 'load session', but no 'store session'");
86 return -1;
87 }
88
89 if (inst->sections.store_session && !inst->sections.load_session) {
90 cf_log_err(server_cs, "Virtual server defines 'store session', but no 'load session'");
91 return -1;
92 }
93
94 /*
95 * If 'load' is set, then 'store' is set. And we must also have 'clear'
96 */
97 if (inst->sections.load_session && !inst->sections.clear_session) {
98 cf_log_err(server_cs, "Virtual server defines 'load session' and 'store session', but no 'clear session'");
99 return -1;
100 }
101
102 if (inst->sections.clear_session) {
103 if (!inst->sections.load_session) {
104 cf_log_err(server_cs, "Virtual server defines 'clear session' but no 'load session'");
105 return -1;
106 }
107
108 if (!inst->sections.store_session) {
109 cf_log_err(server_cs, "Virtual server defines 'clear session' but no 'store session'");
110 return -1;
111 }
112 }
113
114 return 0;
115}
116
117static fr_process_state_t const process_state[] = {
118 [FR_PACKET_TYPE_VALUE_LOAD_SESSION] = {
119 .packet_type = {
120 [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS,
121 [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS,
122
123 [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_FAILURE,
124 [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE,
125 [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE,
126 [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE,
127 [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE,
128 [RLM_MODULE_TIMEOUT] = FR_PACKET_TYPE_VALUE_FAILURE,
129 [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND,
130 },
131 .default_rcode = RLM_MODULE_NOOP,
132 .recv = recv_generic,
133 .resume = resume_recv_no_send,
134 .section_offset = PROCESS_CONF_OFFSET(load_session),
135 },
136 [FR_PACKET_TYPE_VALUE_STORE_SESSION] = {
137 .packet_type = {
138 [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS,
139 [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS,
140
141 [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_FAILURE,
142 [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE,
143 [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE,
144 [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE,
145 [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE,
146 [RLM_MODULE_TIMEOUT] = FR_PACKET_TYPE_VALUE_FAILURE,
147 [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND,
148 },
149 .default_rcode = RLM_MODULE_NOOP,
150 .recv = recv_generic,
151 .resume = resume_recv_no_send,
152 .section_offset = PROCESS_CONF_OFFSET(store_session),
153 },
154 [FR_PACKET_TYPE_VALUE_CLEAR_SESSION] = {
155 .packet_type = {
156 [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS,
157 [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS,
158
159 [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_FAILURE,
160 [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE,
161 [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE,
162 [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE,
163 [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE,
164 [RLM_MODULE_TIMEOUT] = FR_PACKET_TYPE_VALUE_FAILURE,
165 [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND,
166 },
167 .default_rcode = RLM_MODULE_NOOP,
168 .recv = recv_generic,
169 .resume = resume_recv_no_send,
170 .section_offset = PROCESS_CONF_OFFSET(clear_session),
171 },
172 [FR_PACKET_TYPE_VALUE_VERIFY_CERTIFICATE] = {
173 .packet_type = {
174 [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS,
175 [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS,
176 [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_SUCCESS,
177
178 [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE,
179 [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE,
180 [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE,
181 [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE,
182 [RLM_MODULE_TIMEOUT] = FR_PACKET_TYPE_VALUE_FAILURE,
183 [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND,
184 },
185 .default_rcode = RLM_MODULE_NOOP,
186 .recv = recv_generic,
187 .resume = resume_recv_no_send,
188 .section_offset = PROCESS_CONF_OFFSET(verify_certificate),
189 },
190 [FR_PACKET_TYPE_VALUE_NEW_SESSION] = {
191 .packet_type = {
192 [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS,
193 [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS,
194 [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_SUCCESS,
195
196 [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE,
197 [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE,
198 [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE,
199 [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE,
200 [RLM_MODULE_TIMEOUT] = FR_PACKET_TYPE_VALUE_FAILURE,
201 [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND,
202 },
203 .default_rcode = RLM_MODULE_NOOP,
204 .recv = recv_generic,
205 .resume = resume_recv_no_send,
206 .section_offset = PROCESS_CONF_OFFSET(new_session),
207 },
208 [FR_PACKET_TYPE_VALUE_ESTABLISH_SESSION] = {
209 .packet_type = {
210 [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS,
211 [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS,
212 [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_SUCCESS,
213
214 [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE,
215 [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE,
216 [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE,
217 [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE,
218 [RLM_MODULE_TIMEOUT] = FR_PACKET_TYPE_VALUE_FAILURE,
219 [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND
220 },
221 .default_rcode = RLM_MODULE_NOOP,
222 .recv = recv_generic,
223 .resume = resume_recv_no_send,
224 .section_offset = PROCESS_CONF_OFFSET(establish_session),
225 },
226 [FR_PACKET_TYPE_VALUE_FAIL_SESSION] = {
227 .packet_type = {
228 [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS,
229 [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS,
230 [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_SUCCESS,
231
232 [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE,
233 [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE,
234 [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE,
235 [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE,
236 [RLM_MODULE_TIMEOUT] = FR_PACKET_TYPE_VALUE_FAILURE,
237 [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND
238 },
239 .default_rcode = RLM_MODULE_NOOP,
240 .recv = recv_generic,
241 .resume = resume_recv_no_send,
242 .section_offset = PROCESS_CONF_OFFSET(fail_session),
243 },
244 [FR_PACKET_TYPE_VALUE_ENCODE_SESSION] = {
245 .packet_type = {
246 [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS,
247 [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS,
248 [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_SUCCESS,
249
250 [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE,
251 [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE,
252 [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE,
253 [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE,
254 [RLM_MODULE_TIMEOUT] = FR_PACKET_TYPE_VALUE_FAILURE,
255 [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND
256 },
257 .default_rcode = RLM_MODULE_NOOP,
258 .recv = recv_generic,
259 .resume = resume_recv_no_send,
260 .section_offset = PROCESS_CONF_OFFSET(encode_session),
261 },
262 [FR_PACKET_TYPE_VALUE_DECODE_SESSION] = {
263 .packet_type = {
264 [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS,
265 [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS,
266 [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_SUCCESS,
267
268 [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE,
269 [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE,
270 [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE,
271 [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE,
272 [RLM_MODULE_TIMEOUT] = FR_PACKET_TYPE_VALUE_FAILURE,
273 [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND
274 },
275 .default_rcode = RLM_MODULE_NOOP,
276 .recv = recv_generic,
277 .resume = resume_recv_no_send,
278 .section_offset = PROCESS_CONF_OFFSET(decode_session),
279 },
280 [FR_PACKET_TYPE_VALUE_LOAD_PSK] = {
281 .packet_type = {
282 [RLM_MODULE_OK] = FR_PACKET_TYPE_VALUE_SUCCESS,
283 [RLM_MODULE_UPDATED] = FR_PACKET_TYPE_VALUE_SUCCESS,
284 [RLM_MODULE_NOOP] = FR_PACKET_TYPE_VALUE_SUCCESS,
285
286 [RLM_MODULE_REJECT] = FR_PACKET_TYPE_VALUE_FAILURE,
287 [RLM_MODULE_FAIL] = FR_PACKET_TYPE_VALUE_FAILURE,
288 [RLM_MODULE_INVALID] = FR_PACKET_TYPE_VALUE_FAILURE,
289 [RLM_MODULE_DISALLOW] = FR_PACKET_TYPE_VALUE_FAILURE,
290 [RLM_MODULE_TIMEOUT] = FR_PACKET_TYPE_VALUE_FAILURE,
291 [RLM_MODULE_NOTFOUND] = FR_PACKET_TYPE_VALUE_NOTFOUND,
292 },
293 .default_rcode = RLM_MODULE_NOOP,
294 .recv = recv_generic,
295 .resume = resume_recv_no_send,
296 .section_offset = PROCESS_CONF_OFFSET(load_psk),
297 },
298};
299
301{
302 fr_process_state_t const *state;
303
305
307
308 request->component = "tls";
309 request->module = NULL;
310 fr_assert(request->proto_dict == dict_tls);
311
312 /*
313 * Success, failure, and notfound are not TLS packets that we handle.
314 */
315 if (!request->packet->code || (request->packet->code >= FR_PACKET_TYPE_VALUE_SUCCESS)) {
316 REDEBUG("Invalid packet code %u", request->packet->code);
318 }
319
320 UPDATE_STATE(packet);
321
322 log_request_pair_list(L_DBG_LVL_1, request, NULL, &request->request_pairs, NULL);
323
324 return state->recv(p_result, mctx, request);
325}
326
328 {
329 .section = SECTION_NAME("store", "session"),
330 .actions = &mod_actions_authorize,
331 .offset = PROCESS_CONF_OFFSET(store_session)
332 },
333 {
334 .section = SECTION_NAME("load", "session"),
336 .offset = PROCESS_CONF_OFFSET(load_session)
337 },
338 {
339 .section = SECTION_NAME("clear", "session"),
341 .offset = PROCESS_CONF_OFFSET(clear_session)
342 },
343 {
344 .section = SECTION_NAME("verify", "certificate"),
346 .offset = PROCESS_CONF_OFFSET(verify_certificate)
347 },
348 {
349 .section = SECTION_NAME("new", "session"),
351 .offset = PROCESS_CONF_OFFSET(new_session)
352 },
353 {
354 .section = SECTION_NAME("establish", "session"),
356 .offset = PROCESS_CONF_OFFSET(establish_session)
357 },
358 {
359 .section = SECTION_NAME("fail", "session"),
361 .offset = PROCESS_CONF_OFFSET(fail_session)
362 },
363 {
364 .section = SECTION_NAME("encode", "session"),
366 .offset = PROCESS_CONF_OFFSET(encode_session)
367 },
368 {
369 .section = SECTION_NAME("decode", "session"),
371 .offset = PROCESS_CONF_OFFSET(decode_session)
372 },
373 {
374 .section = SECTION_NAME("load", "psk"),
376 .offset = PROCESS_CONF_OFFSET(load_psk)
377 },
379};
380
381
384 .common = {
385 .magic = MODULE_MAGIC_INIT,
386 .name = "tls",
388 MODULE_RCTX(process_rctx_t),
389
391 },
392 .process = mod_process,
393 .compile_list = compile_list,
394 .dict = &dict_tls,
395 .packet_type = &attr_packet_type
396};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
static uint8_t request[4]
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:106
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition cf_util.c:671
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:340
#define cf_parent(_cf)
Definition cf_util.h:115
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:316
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:329
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:335
Specifies an attribute which must be present for the module to function.
Definition dict.h:315
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:328
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
fr_dict_attr_t const * attr_packet_type
Definition base.c:91
static fr_dict_t const * dict_tls
Definition base.c:77
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
Definition log.c:831
@ L_DBG_LVL_1
Highest priority debug messages (-x).
Definition log.h:67
@ FR_TYPE_UINT32
32 Bit unsigned integer.
unlang_mod_actions_t const mod_actions_authorize
Definition mod_action.c:45
unlang_mod_action_t actions[RLM_MODULE_NUMCODES]
Definition mod_action.h:69
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
static unlang_action_t mod_process(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition base.c:168
static const virtual_server_compile_t compile_list[]
Definition base.c:192
static fr_process_state_t const process_state[]
Definition base.c:68
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition base.c:213
CONF_SECTION * decode_session
Definition base.c:58
CONF_SECTION * fail_session
Definition base.c:55
CONF_SECTION * establish_session
Definition base.c:54
fr_process_module_t process_tls
Definition base.c:383
uint64_t nothing
Definition base.c:45
CONF_SECTION * store_session
Definition base.c:51
fr_dict_autoload_t process_tls_dict[]
Definition base.c:31
CONF_SECTION * load_session
Definition base.c:50
CONF_SECTION * encode_session
Definition base.c:57
CONF_SECTION * load_psk
Definition base.c:60
CONF_SECTION * clear_session
Definition base.c:52
fr_dict_attr_autoload_t process_tls_dict_attr[]
Definition base.c:39
CONF_SECTION * verify_certificate
Definition base.c:47
CONF_SECTION * new_session
Definition base.c:49
process_tls_sections_t sections
Definition base.c:64
#define PROCESS_TRACE
Trace each state function as it's entered.
Definition process.h:55
#define PROCESS_CONF_OFFSET(_x)
Definition process.h:79
module_t common
Common fields for all loadable modules.
Common public symbol definition for all process modules.
#define fr_assert(_expr)
Definition rad_assert.h:37
#define REDEBUG(fmt,...)
@ RLM_MODULE_INVALID
The module considers the request invalid.
Definition rcode.h:51
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:49
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:48
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
Definition rcode.h:52
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition rcode.h:47
@ RLM_MODULE_TIMEOUT
Module (or section) timed out.
Definition rcode.h:56
@ RLM_MODULE_NOTFOUND
User not found.
Definition rcode.h:53
@ RLM_MODULE_UPDATED
OK (pairs modified).
Definition rcode.h:55
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:54
#define RETURN_UNLANG_FAIL
Definition rcode.h:69
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:39
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:355
void * data
Module's instance data.
Definition module.h:297
module_instantiate_t instantiate
Callback to allow the module to register any per-instance resources like sockets and file handles.
Definition module.h:228
#define MODULE_RCTX(_ctype)
Definition module.h:262
#define MODULE_INST(_ctype)
Definition module.h:260
eap_aka_sim_process_conf_t * inst
#define talloc_get_type_abort_const
Definition talloc.h:117
section_name_t const * section
Identifier for the section.
#define COMPILE_TERMINATOR
Processing sections which are allowed in this virtual server.