The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
virtual_server.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: 334721a0d9d7a67565752a4231ffd50214bb03bd $
19 *
20 * @file tls/virtual_server.c
21 * @brief Calls a section in the TLS policy virtual server.
22 *
23 * @copyright 2021 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 * @copyright 2026 Network RADIUS SAS (legal@networkradius.com)
25 */
26
27#ifdef WITH_TLS
28#define LOG_PREFIX "tls"
29
30#include <freeradius-devel/unlang/action.h>
31#include <freeradius-devel/unlang/interpret.h>
32#include <freeradius-devel/unlang/call.h>
33#include <freeradius-devel/server/virtual_servers.h>
34
35#include "attrs.h"
36#include "base.h"
37#include "ticket.h"
38
39/** Push a request to perform a policy action using a virtual server
40 *
41 * This function will setup a TLS subrequest to run a virtual server section.
42 *
43 * @note FIXME - The result of these callback sections are ignored... We may
44 * want to change this in the future.
45 *
46 * @param[out] child to run as a subrequest of the parent.
47 * @param[in] resume Function to call after the virtual server
48 * finishes processing the request. uctx will
49 * be a pointer to the provided tls_session.
50 * May be NULL, when nothing needs the result.
51 * @param[in] conf the tls configuration.
52 * @param[in] tls_session The current tls_session.
53 * @param[in] cache_required Does this action require the tls cache
54 * @return
55 * - UNLANG_ACTION_PUSHED_CHILD on success.
56 * - UNLANG_ACTION_FAIL on failure.
57 */
58unlang_action_t fr_tls_call_push(request_t *child, unlang_function_no_result_t resume,
59 fr_tls_conf_t *conf, fr_tls_session_t *tls_session,
60#ifdef NDEBUG
61 UNUSED
62#endif
63 bool cache_required)
64{
65 fr_assert(tls_session->cache || !cache_required);
66
67 /*
68 * The caller MUST have checked if a virtual server is
69 * available. If not, then the 'child' request has been
70 * built and allocated for no purpose.
71 *
72 * unlang_call_push() below is nonnull, so a NULL
73 * virtual_server must not reach it. Every caller frees the
74 * child when this function fails, so returning here leaks
75 * nothing.
76 */
77 if (!fr_cond_assert_msg(conf->virtual_server != NULL,
78 "TLS configuration has no virtual_server, so no policy section can run")) {
79 return UNLANG_ACTION_FAIL;
80 }
81
82 /*
83 * Sets up a dispatch frame in the parent
84 * and a result processing frame in the child.
85 */
86 if (unlang_subrequest_child_push(NULL, child,
87 tls_session,
88 true, UNLANG_SUB_FRAME) < 0) {
90 return UNLANG_ACTION_FAIL;
91 }
92
93 /*
94 * Setup a function to execute after the
95 * subrequest completes.
96 */
97 if (resume && !fr_cond_assert(unlang_function_push(child,
98 NULL,
99 resume,
100 NULL,
102 tls_session) == UNLANG_ACTION_PUSHED_CHILD)) {
103 /*
104 * We just pushed the child frame onto the stack.
105 * We don't want the subrequest to execute, if we then
106 * failed to push the function that executes after it
107 * returns.
108 */
109 error:
110 unlang_interpet_frame_discard(child->parent);
112 return UNLANG_ACTION_FAIL;
113 }
114
115 /*
116 * Now the child and parent stacks are both
117 * setup correctly, push a virtual server
118 * call into the subrequest to run the section
119 * specified by Packet-Type.
120 */
121 if (unlang_call_push(NULL, child, conf->virtual_server, UNLANG_SUB_FRAME) < 0) goto error;
122
124}
125#endif
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
Definition action.h:40
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
Definition action.h:36
#define UNUSED
Definition build.h:415
unlang_action_t unlang_call_push(unlang_result_t *p_result, request_t *request, CONF_SECTION *server_cs, bool top_frame)
Push a virtual server CONF_SECTION as a call frame onto the stack.
Definition call.c:151
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:177
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:194
unlang_action_t(* unlang_function_no_result_t)(request_t *request, void *uctx)
A generic function pushed by a module or xlat to functions deeper in the C call stack to create resum...
Definition function.h:68
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
Definition function.h:181
void unlang_interpet_frame_discard(request_t *request)
Discard the bottom most frame on the request's stack.
Definition interpret.c:2511
#define UNLANG_SUB_FRAME
Definition interpret.h:37
#define fr_assert(_expr)
Definition rad_assert.h:37
static rs_t * conf
Definition radsniff.c:52
#define request_is_detachable(_x)
Definition request.h:188
@ FR_SIGNAL_NONE
No signals.
Definition signal.h:39
int unlang_subrequest_child_push(unlang_result_t *p_result, request_t *child, void const *unique_session_ptr, bool free_child, bool top_frame)
Push a pre-existing child back onto the stack as a subrequest.
Definition subrequest.c:440