The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
connection.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17#ifdef WITH_TLS
18/**
19 * $Id: 4f92e29216aeae5a3cbf23c1b6a157a5921c8489 $
20 *
21 * @file lib/tls/connection.h
22 * @brief Run one TLS connection from the first policy section to the last.
23 *
24 * A TLS session is the handshake. A TLS connection is the handshake, the
25 * policy which runs before and after the handshake, and the cache operations
26 * the handshake queues. fr_tls_session_t holds the handshake.
27 * fr_tls_connection_t holds the connection, and drives fr_tls_session_t.
28 *
29 * @copyright 2026 Network RADIUS SAS (legal@networkradius.com)
30 */
31RCSIDH(tls_connection_h, "$Id: 4f92e29216aeae5a3cbf23c1b6a157a5921c8489 $")
32
33#include "openssl_user_macros.h"
34
35#include <freeradius-devel/unlang/action.h>
36#include <freeradius-devel/unlang/function.h>
37#include <freeradius-devel/util/timer.h>
38
39#include "conf.h"
40#include "session.h"
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/** The state of the TLS connection.
47 *
48 * The connection state goes from new, to "doing handshakes", to
49 * "doing ticket callbacks", to "connected".
50 *
51 * TICKET is not the same as CONNECTED, because TLS 1.3 sends tickets
52 * after the handshake, but before the application data. In TLS 1.2,
53 * the state goes from HANDSHAKE directly to CONNECTED.
54 *
55 * There is no substantial difference between HANDSHAKE and TICKET,
56 * except to give more visibility into the state of the connection.
57 */
58typedef enum : uint8_t {
59 TLS_CONNECTION_NEW_SESSION = 0, //!< Run `new session { ... }`.
60 TLS_CONNECTION_HANDSHAKE, //!< Run handshake rounds until the handshake ends.
61 TLS_CONNECTION_TICKET, //!< Run the ticket and cache operations which the
62 ///< handshake queued.
63 TLS_CONNECTION_CONNECTED //!< Every ticket section has finished. The
64 ///< connection can carry application data.
65} fr_tls_connection_state_t;
66
67/** Give the reason why the connection failed
68 *
69 */
70typedef enum : uint8_t {
71 TLS_CONNECTION_FAIL_NONE = 0, //!< no failure as of yet
72 TLS_CONNECTION_FAIL_TLS, //!< failure inside of TLS
73 TLS_CONNECTION_FAIL_SYSCALL, //!< system call, usually IO layer
74 TLS_CONNECTION_FAIL_APPLICATION, //!< other application error
75} fr_tls_connection_fail_t;
76
77/** IO state. Did the read / write succeed, etc?
78 *
79 * An application does IO, as the TLS library should not do any IO.
80 *
81 * The application still needs to inform the TLS library as to the state
82 * of the underlying connection. This enum does that.
83 *
84 * The values here should be the same for all applications. If
85 * they're not, we can add new values.
86 *
87 * New connections start off with state 0 (FR_TLS_CONNECTION_IO_OK).
88 */
89typedef enum : uint8_t {
90 FR_TLS_CONNECTION_IO_OK = 0, //!< The call succeeded, or no call has been
91 ///< made yet.
92 FR_TLS_CONNECTION_IO_RETRY, //!< A signal interrupted the call. Run the
93 ///< call again.
94 FR_TLS_CONNECTION_IO_BLOCKED, //!< The call would block. Wait for the socket
95 ///< to become ready.
96 FR_TLS_CONNECTION_IO_EOF, //!< The peer closed the connection. On a stream
97 ///< a read() which returns zero means the same
98 ///< thing.
99 FR_TLS_CONNECTION_IO_FATAL, //!< The connection cannot continue.
100} fr_tls_connection_io_state_t;
101
102/** Tables which map enumeration values to names.
103 *
104 @verbatim
105 DEBUG("%s - connection failed: %s", conn->name,
106 fr_table_str_by_value(fr_tls_connection_fail_table, conn->failed, "<INVALID>"));
107 @endverbatim
108 */
109extern fr_table_num_indexed_t const fr_tls_connection_state_table[];
110extern size_t fr_tls_connection_state_table_len;
111
112extern fr_table_num_indexed_t const fr_tls_connection_fail_table[];
113extern size_t fr_tls_connection_fail_table_len;
114
115extern fr_table_num_indexed_t const fr_tls_connection_io_state_table[];
116extern size_t fr_tls_connection_io_state_table_len;
117
118/** Everything the TLS connection state machine needs
119 *
120 * The state machine is the set of functions in src/lib/tls/connection.c.
121 * Every field the state machine reads or writes lives in fr_tls_connection_t,
122 * and the state machine reads no other structure.
123 *
124 * fr_tls_connection_t must be talloc'd, and must not be embedded in another
125 * structure. `name` is allocated from the connection, so the connection has
126 * to be a talloc chunk of its own.
127 *
128 * The state machine performs two actions which are outside of TLS state
129 * management:
130 *
131 * - telling the calling application that the TLS connection has finished,
132 * whether the connection succeeded or failed
133 * - writing the data OpenSSL produced out to the peer
134 *
135 * Both actions belong to the application which owns the connection, so the
136 * state machine calls the `finished` and `write` callbacks rather than
137 * performing either action itself.
138 */
139typedef struct fr_tls_connection_s fr_tls_connection_t;
140
141struct fr_tls_connection_s {
142 char const *name; //!< What to call this connection in log messages,
143
144 fr_tls_session_t *tls_session; //!< State of the handshake.
145 request_t *request; //!< Request the handshake runs under.
146 ///< MUST be set, and MUST live longer than the connection.
147
148 fr_tls_connection_state_t state; //!< Which part of the connection is running.
149
150 bool in_frame; //!< tls_connection_frame_process() is running.
151 ///< A wake raised while the frame runs cannot go
152 ///< to the interpreter, because the request has
153 ///< not yielded yet, so the frame takes it.
154 bool wake_pending; //!< A wake was raised while `in_frame` was set.
155
156 unlang_function_no_result_t process; //!< The connection runs its own state machine
157 ///< inside one unlang frame, and this is the
158 ///< function that machine runs next. The
159 ///< interpreter does not know about it:
160 ///< tls_connection_frame_process() is the only
161 ///< thing the interpreter sees, and that function
162 ///< calls this one. NULL means the connection's
163 ///< state machine has finished.
164
165 fr_tls_connection_fail_t failed; //!< why the connection failed
166 int error; //!< for system call errors
167
168 fr_timer_list_t *tl; //!< DTLS retransmission timer list
169 fr_timer_t *post_handshake_ev; //!< Bounds the wait for whatever the peer still owes
170 ///< once OpenSSL has finished. A TLS 1.3 peer is
171 ///< owed a session ticket, and nothing else times
172 ///< that wait.
173 fr_timer_t *timer_ev; //!< DTLS retransmission timer event
174 ///< can be re-used by the application for application data
175
176 fr_tls_connection_io_state_t io_state; //!< IO state, set by the application
177
178 bool client; //!< Act as the client and connect to a server,
179 ///< rather than accept a connection.
180 bool idle; //!< The connection frame has yielded, and waits
181 ///< for a record.
182 bool pending; //!< A record is waiting for OpenSSL.
183 bool fail_pending; //!< fr_tls_connection_failed() was called while a
184 ///< record was still waiting for OpenSSL. The
185 ///< connection ends later, once OpenSSL has processed
186 ///< any pending TLS alerts.
187 bool eof; //!< The peer closed the connection. A record the peer
188 ///< sent before closing may still be pending, and may
189 ///< complete the handshake. The connection fails only
190 ///< if the handshake reads that record and then
191 ///< determines it needs another record.
192
193 void *uctx; //!< Context for the callback functions below.
194 ///< The callbacks read `conn->uctx` rather than
195 ///< taking the context as an argument, so that
196 ///< adding a callback does not mean repeating
197 ///< the same first parameter again.
198
199 void (*connected)(fr_tls_connection_t *conn);
200 //!< TLS is connected, and the application can send data
201 void (*close)(fr_tls_connection_t *conn);
202 //!< TLS is closing the connection
203 ssize_t (*write)(fr_tls_connection_t *conn,
204 uint8_t const *data, size_t size);
205 //!< Write `size` octets at `data` to the
206 ///< peer. Returns <0 on failure, or the
207 ///< amount of data written >=0.
208};
209
210fr_tls_connection_t *fr_tls_connection_alloc(TALLOC_CTX *ctx, fr_timer_list_t *tl,
211 ssize_t (*write)(fr_tls_connection_t *conn,
212 uint8_t const *data, size_t size),
213 void (*connected)(fr_tls_connection_t *conn),
214 void (*close)(fr_tls_connection_t *conn));
215
216int fr_tls_connection_push(fr_tls_connection_t *conn);
217
218void fr_tls_connection_wake(fr_tls_connection_t *conn);
219
220void fr_tls_connection_failed(fr_tls_connection_t *conn, fr_tls_connection_fail_t reason);
221
222void fr_tls_connection_eof(fr_tls_connection_t *conn);
223
224fr_tls_connection_io_state_t fr_tls_connection_io_error(fr_tls_connection_t *conn, ssize_t slen);
225
226void fr_tls_connection_recv(fr_tls_connection_t *conn, uint8_t const *data, size_t data_len);
227
228int fr_tls_connection_write(fr_tls_connection_t *conn);
229
230void fr_tls_connection_process(fr_tls_connection_t *conn);
231
232#ifdef __cplusplus
233}
234#endif
235#endif /* WITH_TLS */
static uint8_t request[4]
#define RCSIDH(h, id)
Definition build.h:604
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
long int ssize_t
unsigned char uint8_t
static char const * name
An element in a table indexed by numeric value.
Definition table.h:92
An event timer list.
Definition timer.c:49
A timer event.
Definition timer.c:83
static fr_slen_t data
Definition value.h:1366