The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
connection.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: b2f4eb78975a968b27fdb632a6831ef472ffd43a $
19 *
20 * @file tls/connection.c
21 * @brief Run one TLS connection from the first policy section to the last
22 *
23 * The state machine runs under one connection frame, which fr_tls_connection_push()
24 * pushes. Each state sets up frame->repeat as the next state, and which then
25 * lets the current state push children.
26 *
27 * @copyright 2026 Network RADIUS SAS (legal@networkradius.com)
28 */
29#ifdef WITH_TLS
30#define LOG_PREFIX "tls"
31#define _TLS_PRIVATE 1
32
33#include <freeradius-devel/unlang/function.h>
34#include <freeradius-devel/unlang/interpret.h>
35
36#include <freeradius-devel/protocol/tls/freeradius.h>
37
38#include "base.h"
39#include "ticket.h"
40#include "connection.h"
41#include "dtls.h"
42#include "log.h"
43
44fr_table_num_indexed_t const fr_tls_connection_state_table[] = {
45 [TLS_CONNECTION_NEW_SESSION] = { L("new_session"), TLS_CONNECTION_NEW_SESSION },
46 [TLS_CONNECTION_HANDSHAKE] = { L("handshake"), TLS_CONNECTION_HANDSHAKE },
47 [TLS_CONNECTION_TICKET] = { L("ticket"), TLS_CONNECTION_TICKET },
48 [TLS_CONNECTION_CONNECTED] = { L("connected"), TLS_CONNECTION_CONNECTED }
49};
50size_t fr_tls_connection_state_table_len = NUM_ELEMENTS(fr_tls_connection_state_table);
51
52fr_table_num_indexed_t const fr_tls_connection_fail_table[] = {
53 [TLS_CONNECTION_FAIL_NONE] = { L("none"), TLS_CONNECTION_FAIL_NONE },
54 [TLS_CONNECTION_FAIL_TLS] = { L("tls"), TLS_CONNECTION_FAIL_TLS },
55 [TLS_CONNECTION_FAIL_SYSCALL] = { L("syscall"), TLS_CONNECTION_FAIL_SYSCALL },
56 [TLS_CONNECTION_FAIL_APPLICATION] = { L("application"), TLS_CONNECTION_FAIL_APPLICATION }
57};
58size_t fr_tls_connection_fail_table_len = NUM_ELEMENTS(fr_tls_connection_fail_table);
59
60fr_table_num_indexed_t const fr_tls_connection_io_state_table[] = {
61 [FR_TLS_CONNECTION_IO_OK] = { L("ok"), FR_TLS_CONNECTION_IO_OK },
62 [FR_TLS_CONNECTION_IO_RETRY] = { L("retry"), FR_TLS_CONNECTION_IO_RETRY },
63 [FR_TLS_CONNECTION_IO_BLOCKED] = { L("blocked"), FR_TLS_CONNECTION_IO_BLOCKED },
64 [FR_TLS_CONNECTION_IO_EOF] = { L("eof"), FR_TLS_CONNECTION_IO_EOF },
65 [FR_TLS_CONNECTION_IO_FATAL] = { L("fatal"), FR_TLS_CONNECTION_IO_FATAL }
66};
67size_t fr_tls_connection_io_state_table_len = NUM_ELEMENTS(fr_tls_connection_io_state_table);
68
69/** Wake the connection's request, if the request is waiting for a record
70 *
71 * The request yields in two places: the connection frame waiting for
72 * a record, and a policy section which pushed under the connection
73 * frame. Only a request which is yielded in the connection frame can
74 * be woken from outside.
75 *
76 * The request may push a subrequest, which runs policies to establish
77 * sessions, load / save session cache entries, etc. The parent
78 * request must wait until the subrequest is finished before it can
79 * continue. Erroneously waking a request while the subrequest is
80 * running will strand the subrequest on the runnable heap.
81 */
82static void tls_connection_request_wake(fr_tls_connection_t *conn)
83{
84 if (!conn->idle) return;
85
86 conn->idle = false;
87
88 /*
89 * The frame is running, so the request has not yielded, and
90 * marking it runnable now would be lost. Tell the frame
91 * instead: it runs the state machine again before it yields.
92 */
93 if (conn->in_frame) {
94 conn->wake_pending = true;
95 return;
96 }
97
98 unlang_interpret_mark_runnable(conn->request);
99}
100
101/** Response timeout for post handshake packets.
102 *
103 * TLS handshake finished is not the same as connected. TLS 1.3 sends session tickets after
104 * SSL_is_init_finished(). We need to bound the time that we wait for the ticket.
105 */
106#define TLS_POST_HANDSHAKE_TIMEOUT fr_time_delta_from_sec(2)
107
108/** The peer didn't send anything after TLS handshake finished.
109 *
110 */
111static void _tls_connection_post_handshake_timeout(UNUSED fr_timer_list_t *tl, UNUSED fr_time_t now, void *uctx)
112{
113 fr_tls_connection_t *conn = talloc_get_type_abort(uctx, fr_tls_connection_t);
114 request_t *request = conn->request;
115
116 REDEBUG("(TLS) %s - Timed out waiting for data after the handshake completed", conn->name);
117
118 fr_tls_session_error_add(request, FR_ERROR_VALUE_POST_HANDSHAKE_TIMEOUT);
119 fr_tls_connection_failed(conn, TLS_CONNECTION_FAIL_TLS);
120}
121
122/** Decide whether the handshake is over, and whether the handshake succeeded
123 *
124 * The handshake is complete only when fr_tls_session_is_init_finished()
125 * returns true and every record produced by OpenSSL has reached the peer.
126 * That is not the same as OpenSSL's own SSL_is_init_finished(): with a
127 * TLS 1.3 stateless ticket there is a `load session` still to run.
128 */
129static void tls_connection_check(fr_tls_connection_t *conn)
130{
131 fr_tls_session_t *tls_session = conn->tls_session;
132 request_t *request = conn->request;
133
134 /*
135 * The cache load / save operations can wake the parent
136 * request, and change the state of the parents
137 * connection.
138 */
139 if (conn->state != TLS_CONNECTION_HANDSHAKE) return;
140
141 /*
142 * fr_tls_connection_failed() was called while a record was
143 * still waiting for OpenSSL. `idle` says the frame has read
144 * everything and is waiting for a record which is not coming,
145 * so the failure can be acted on now.
146 */
147 if (conn->fail_pending) {
148 if (!conn->idle) return;
149
150 conn->fail_pending = false;
151 goto finish;
152 }
153
154 /*
155 * The peer closed the connection, and the handshake has read
156 * every record it was given and now needs another one. No
157 * more records will arrive, so the handshake cannot complete.
158 *
159 * If the last record completed the handshake instead, the
160 * frame may be idle as well, but fr_tls_session_is_init_finished()
161 * is true, and the completion is reported below.
162 */
163 if (conn->eof && conn->idle && !fr_tls_session_is_init_finished(tls_session)) {
164 REDEBUG("(TLS) Peer closed the connection before the handshake completed");
165 errno = 0; /* fr_tls_connection_failed() records errno, and no call set one */
166 fr_tls_connection_failed(conn, TLS_CONNECTION_FAIL_SYSCALL);
167 return;
168 }
169
170 if (tls_session->result == FR_TLS_RESULT_ERROR) {
171 fr_tls_log_perror(conn->request, "TLS handshake failed");
172
173 /*
174 * This sets the state and wakes the request, which is
175 * what the code under `finish` does for the success
176 * path. Doing both would do the same work twice.
177 */
178 fr_tls_connection_failed(conn, TLS_CONNECTION_FAIL_TLS);
179 return;
180 }
181
182 /*
183 * The TLS handshake is continuing, OR it's done but
184 * there's still data to push to the peer.
185 */
186 if (!fr_tls_session_is_init_finished(tls_session)) {
187 /*
188 * OpenSSL is done, but the session is not: the peer
189 * still owes us the records which finish it, which for
190 * TLS 1.3 is a session ticket. Bound that wait, because
191 * nothing else does, and a peer which never sends them
192 * would otherwise hold the connection open for good.
193 */
194 if (SSL_is_init_finished(tls_session->ssl) && !conn->post_handshake_ev &&
195 fr_timer_in(conn, conn->tl, &conn->post_handshake_ev,
196 TLS_POST_HANDSHAKE_TIMEOUT, false,
197 _tls_connection_post_handshake_timeout, conn) < 0) {
198 fr_tls_log_error("Failed arming the post-handshake timer");
199 fr_tls_connection_failed(conn, TLS_CONNECTION_FAIL_APPLICATION);
200 }
201
202 return;
203 }
204
205 FR_TIMER_DELETE(&conn->post_handshake_ev);
206
207 if (fr_dbuff_remaining(tls_session->dirty_out) > 0) return;
208
209 INFO("%s - TLS handshake completed", conn->name);
210 INFO(" version : %s", SSL_get_version(tls_session->ssl));
211 INFO(" cipher : %s", SSL_get_cipher(tls_session->ssl));
212 INFO(" resumed : %s", SSL_session_reused(tls_session->ssl) ? "yes" : "no");
213
214finish:
215 /*
216 * The cache callbacks push work onto the request stack,
217 * and the request is idle. We need to wake up the
218 * request.
219 *
220 * We're running in a callback, and not as part of a
221 * frame process function. We therefore change the state
222 * (not the process function), and then wake up the
223 * request. The frame process function will see that
224 * state change, and switch to the new function.
225 */
226 conn->state = TLS_CONNECTION_TICKET;
227 tls_connection_request_wake(conn);
228}
229
230/** Tell the application that the connection is closed
231 *
232 * This function should be used after all policies have been run. A caller which needs to run policies should
233 * use fr_tls_connection_failed() instead.
234 *
235 * @param[in] conn which failed.
236 */
237static void tls_connection_close(fr_tls_connection_t *conn)
238{
239 request_t *request = conn->request;
240
241 /*
242 * Both callers record why the connection failed before calling
243 * this function, so recording a reason here would overwrite the
244 * one the caller knew.
245 */
246 fr_assert(conn->failed != TLS_CONNECTION_FAIL_NONE);
247
248 conn->idle = false;
249 FR_TIMER_DELETE(&conn->timer_ev);
250 FR_TIMER_DELETE(&conn->post_handshake_ev);
251 TALLOC_FREE(conn->tl);
252
253 RDEBUG2("(TLS) %s - closing connection", conn->name);
254 conn->close(conn);
255}
256
257/** Tell the application that the connection is connected
258 *
259 * Every ticket section has finished, so the connection can carry application
260 * data from here on.
261 */
262static unlang_action_t tls_connection_connected(request_t *request, void *uctx)
263{
264 fr_tls_connection_t *conn = talloc_get_type_abort(uctx, fr_tls_connection_t);
265
266 conn->idle = false;
267
268 /*
269 * fr_tls_ticket_stateful_store_session() and fr_tls_ticket_stateful_clear_session()
270 * run every queued cache operation before either function
271 * returns. An operation still queued here would never run at
272 * all, and the session would silently not be cached, or would
273 * silently not be cleared.
274 */
275 fr_assert(!fr_tls_ticket_stateful_pending(conn->tls_session->cache));
276
277 /*
278 * We're run the ticket policies, but something failed.
279 * `fail session` ends up here, too.
280 */
281 if (conn->failed) {
282 tls_connection_close(conn);
283 return UNLANG_ACTION_YIELD;
284 }
285
286 if (conn->state == TLS_CONNECTION_CONNECTED) return UNLANG_ACTION_YIELD;
287
288 /*
289 * We've successfully run all ticket policies. The connection can now carry application data.
290 */
291 conn->state = TLS_CONNECTION_CONNECTED;
292 FR_TIMER_DELETE(&conn->timer_ev);
293
294 RDEBUG2("(TLS) %s - connection state is now %s", conn->name,
295 fr_table_str_by_value(fr_tls_connection_state_table, conn->state, "<INVALID>"));
296
297 /*
298 * Tell the application that the connection is up.
299 */
300 conn->connected(conn);
301
302 return UNLANG_ACTION_YIELD;
303}
304
305
306/** Record a fatal error found outside of the interpreter
307 *
308 * The IO callbacks run outside of the interpreter, and so have no stack
309 * frame of their own. They cannot run policy. So they do what
310 * tls_connection_check() does for a failed handshake: record the failure,
311 * change the state, and wake the request. The connection frame then runs
312 * `fail session { ... }`, discards the session, and tells the application.
313 *
314 * The wake is not always possible, and does not have to be. A request
315 * which is running a policy subrequest is deliberately not woken, see
316 * tls_connection_request_wake(). The state change still stands, and the
317 * connection frame acts on the state change when the subrequest finishes.
318 *
319 * Typically this means that the connection frame runs the `fail connection` policy.
320 *
321 * An application should call this function to indicate a socket or other connection failure during TLS
322 * negotiation. The handshake stops, `fail session { ... }` runs, and the `finished` callback reports the
323 * failure once the policy is done.
324 *
325 * The rule is, inside of a frame which is checking the TLS parameters, set conn->failed; outside the frame,
326 * call fr_tls_connection_failed().
327 *
328 * @param[in] conn which failed.
329 */
330void fr_tls_connection_failed(fr_tls_connection_t *conn, fr_tls_connection_fail_t reason)
331{
332 request_t *request = conn->request;
333
334 fr_assert(reason != TLS_CONNECTION_FAIL_NONE);
335
336 if (conn->failed) return;
337
338 conn->failed = reason;
339 if (conn->failed == TLS_CONNECTION_FAIL_SYSCALL) conn->error = errno;
340
341 RDEBUG2("(TLS) %s - connection failed: %s", conn->name,
342 fr_table_str_by_value(fr_tls_connection_fail_table, conn->failed, "<INVALID>"));
343
344 /*
345 * Record the reason where `fail session { ... }` reads it.
346 *
347 * A failure inside TLS gets no value here. Either one of the
348 * rules in src/lib/tls/alerts.md already recorded a value which
349 * says what the rule was, or OpenSSL raised the error and
350 * fr_tls_log_perror() has already reported what OpenSSL said. A value
351 * meaning "something in TLS went wrong" would displace neither
352 * and add nothing.
353 */
354 switch (reason) {
355 case TLS_CONNECTION_FAIL_SYSCALL:
356 fr_tls_session_error_add(conn->request, FR_ERROR_VALUE_SYSTEM_CALL_FAILED);
357 break;
358
359 case TLS_CONNECTION_FAIL_APPLICATION:
360 fr_tls_session_error_add(conn->request, FR_ERROR_VALUE_APPLICATION_FAILED);
361 break;
362
363 default:
364 break;
365 }
366
367 /*
368 * The connection frame is either initializing, or has finished all TLS negotiation, and has
369 * received application data. Just run the callback, and not any policies.
370 */
371 if (conn->state != TLS_CONNECTION_HANDSHAKE) {
372 tls_connection_close(conn);
373 return;
374 }
375
376 /*
377 * We were called while there's pending data for OpenSSL. Likely from an IO callback.
378 *
379 * The connection may be dead (after a read), but the buffer is likely to contain a TLS Alert.
380 * Keep the TLS state machine alive until we've read and processed any pending TLS alerts
381 *
382 * Let the handshake read the record. tls_connection_check() ends the connection once the frame
383 * has finished it's state machine, and gone idle.
384 */
385 if (conn->pending) {
386 conn->fail_pending = true;
387 tls_connection_request_wake(conn);
388 return;
389 }
390
391 /*
392 * We failed during TLS negotiation, we're done with the connection. Wake up the request so that
393 * it can run `fail connection`.
394 */
395 conn->state = TLS_CONNECTION_TICKET;
396 tls_connection_request_wake(conn);
397}
398
399/** Record that the peer closed the connection
400 *
401 * The peer may have sent a record just before closing. If that record is
402 * still pending, it may be the one that completes the handshake, so the
403 * request is woken to process it. tls_connection_check() then fails the
404 * connection only if the handshake reads the record and determines it
405 * needs another one.
406 *
407 * If nothing is pending, the handshake is waiting for a record that will
408 * never arrive, so the connection fails immediately.
409 *
410 * @param[in] conn the peer closed.
411 */
412void fr_tls_connection_eof(fr_tls_connection_t *conn)
413{
414 request_t *request = conn->request;
415
416 conn->eof = true;
417 fr_tls_session_error_add(request, FR_ERROR_VALUE_PEER_CLOSED_CONNECTION);
418
419 if (conn->pending) {
420 tls_connection_request_wake(conn);
421 return;
422 }
423
424 REDEBUG("(TLS) Peer closed the connection before the handshake completed");
425 errno = 0; /* fr_tls_connection_failed() records errno, and no call set one */
426 fr_tls_connection_failed(conn, TLS_CONNECTION_FAIL_SYSCALL);
427}
428
429/** Look at slen / errno to see why IO failed, and act on it.
430 *
431 * The decision is recorded in `conn->io_state` and `errno` in `conn->error`, which lets other code know
432 * exactly what went wrong, and why.
433 *
434 * The application write function should call this function, and then check its return value. The writer
435 * should return on fatal errors or EOF, or otherwise retry.
436 *
437 * We leave out EMSGSIZE, ENETDOWN, and ENETUNREACH. These are recoverable only for unconnected datagram
438 * sockets, where we can re-send the datagram later, or send other datagrams to different destinations. For
439 * connected sockets, those errors are fatal.
440 *
441 * @param[in] conn the call was made on.
442 * @param[in] slen which the call returned. Zero and negative values are
443 * classified, a positive value is not an error.
444 * @return the classification, which is also left in `conn->io_state`.
445 */
446fr_tls_connection_io_state_t fr_tls_connection_io_error(fr_tls_connection_t *conn, ssize_t slen)
447{
448 request_t *request = conn->request;
449 int error = errno;
450
451 /*
452 * Nothing failed, so there is nothing to classify.
453 */
454 if (slen > 0) {
455 conn->io_state = FR_TLS_CONNECTION_IO_OK;
456 conn->error = 0;
457 return conn->io_state;
458 }
459
460 /*
461 * A zero-read is "EOF" for stream sockets, and "no data"
462 * for datagram sockets.
463 */
464 if (slen == 0) {
465 error = 0;
466
467 if (conn->tls_session && (conn->tls_session->socket_type == SOCK_DGRAM)) {
468 conn->io_state = FR_TLS_CONNECTION_IO_OK;
469 goto act;
470 }
471
472 conn->io_state = FR_TLS_CONNECTION_IO_EOF;
473 goto act;
474 }
475
476 switch (error) {
477 case EINTR:
478 conn->io_state = FR_TLS_CONNECTION_IO_RETRY;
479 break;
480
481#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
482 case EWOULDBLOCK:
483#endif
484 case EAGAIN:
485 conn->io_state = FR_TLS_CONNECTION_IO_BLOCKED;
486 break;
487
488 /*
489 * The peer closed the connection, or reset the connection, or
490 * went away while the connection was being written to.
491 */
492 case ECONNRESET:
493 case ENOTCONN:
494 case EPIPE:
495 conn->io_state = FR_TLS_CONNECTION_IO_EOF;
496 break;
497
498 default:
499 conn->io_state = FR_TLS_CONNECTION_IO_FATAL;
500 break;
501 }
502
503act:
504 switch (conn->io_state) {
505 /*
506 * The caller runs the call again, or waits for the socket.
507 * Either way the connection carries on.
508 */
509 case FR_TLS_CONNECTION_IO_OK:
510 case FR_TLS_CONNECTION_IO_RETRY:
511 case FR_TLS_CONNECTION_IO_BLOCKED:
512 break;
513
514 /*
515 * A record the peer sent before closing may still be pending,
516 * and may be the one which completes the handshake, so this
517 * does not always end the connection at once.
518 */
519 case FR_TLS_CONNECTION_IO_EOF:
520 fr_tls_connection_eof(conn);
521 break;
522
523 case FR_TLS_CONNECTION_IO_FATAL:
524 fr_tls_session_error_add(request, FR_ERROR_VALUE_SYSTEM_CALL_FAILED);
525 fr_tls_connection_failed(conn, TLS_CONNECTION_FAIL_SYSCALL);
526 break;
527 }
528
529 /*
530 * Set this last. fr_tls_connection_eof() and
531 * fr_tls_connection_failed() both record errno themselves, and
532 * the first of those clears errno before it does, which would
533 * otherwise discard what the socket reported.
534 */
535 conn->error = error;
536
537 RDEBUG3("(TLS) %s - IO state is now %s", conn->name,
538 fr_table_str_by_value(fr_tls_connection_io_state_table, conn->io_state, "<INVALID>"));
539
540 return conn->io_state;
541}
542
543/** Set or clear the connections processing function
544 *
545 * The TLS connection needs to run its own state machine, and once that returns, do a standard set of
546 * post-processing via fr_tls_connection_process().
547 */
548#define TLS_CONNECTION_FUNC_SET(_conn, _func) (_conn)->process = (_func)
549#define TLS_CONNECTION_FUNC_CLEAR(_conn) (_conn)->process = NULL
550
551/** There is a fatal connection error.
552 *
553 * The state functions have no way to report a failure to the
554 * interpreter, because we're pushing functions onto the stack with
555 * unlang_function_push(), instead of unlang_function_push_with_result().
556 *
557 * We therefore record the failure, discard the session, and return yield.
558 *
559 * @param[in] request running the connection frame.
560 * @param[in] conn which failed.
561 * @return
562 * - UNLANG_ACTION_PUSHED_CHILD - `clear session { ... }` is running.
563 * - UNLANG_ACTION_YIELD - the application has been told.
564 */
565static unlang_action_t tls_connection_error(request_t *request, fr_tls_connection_t *conn)
566{
568
569 /*
570 * Record the reason, and nothing else. This function runs
571 * inside the connection frame, and runs the failure policy
572 * itself, a few lines below. fr_tls_connection_failed() is for
573 * a caller outside the frame which needs the frame to run that
574 * policy, so calling it here would ask the frame to do what the
575 * frame is already doing. Worse, the macros below are also used
576 * while the cache operations run, and at that point
577 * fr_tls_connection_failed() tells the application that the
578 * connection is over, leaving the push below to run against a
579 * connection which has already reported its result.
580 */
581 conn->failed = TLS_CONNECTION_FAIL_TLS;
582 conn->idle = false;
583
584 /*
585 * Clear any pending repeat, so that the TLS state machine functions aren't used.
586 */
587 TLS_CONNECTION_FUNC_CLEAR(conn);
588
589 /*
590 * Set our own repeat, which closes the connection, as is
591 * done in tls_connection_ticket(). We have to
592 * set a repeat function to a "connection done" function,
593 * as fr_tls_session_fail_session() may push a child. That runs
594 * `fail session { ... }`, and then the `clear session`
595 * code.
596 */
597 TLS_CONNECTION_FUNC_SET(conn, tls_connection_connected);
598
599 ua = fr_tls_session_fail_session(request, conn->tls_session);
600 if (ua == UNLANG_ACTION_PUSHED_CHILD) return ua;
601
602 /*
603 * Nothing was pushed, so we clear our repeat and return
604 * that the TLS connection failed.
605 *
606 * If the push failed, then nothing should have been
607 * pushed onto the stack. The cache operations are
608 * marked as "need to be run", but we can't do anything
609 * else. So we just return, and potentially leave any
610 * cache entries behind.
611 */
612 TLS_CONNECTION_FUNC_CLEAR(conn);
613
614 tls_connection_close(conn);
615 return UNLANG_ACTION_YIELD;
616}
617
618#define TLS_CONNECTION_ERROR_RETURN \
619 do { \
620 if (ua == UNLANG_ACTION_PUSHED_CHILD) return ua; \
621 if (ua == UNLANG_ACTION_FAIL) return tls_connection_error(request, conn); \
622 } while (0)
623
624/** Run the ticket and cache operations which the handshake queued
625 *
626 * The handshakes are done, either due to success or failure. On
627 * failure, we discard any cached session. On success, we store the
628 * session before processing application data.
629 */
630static unlang_action_t tls_connection_ticket(request_t *request, void *uctx)
631{
632 fr_tls_connection_t *conn = talloc_get_type_abort(uctx, fr_tls_connection_t);
634
635 conn->idle = false;
636
637 /*
638 * Arm the repeat before any push.
639 */
640 TLS_CONNECTION_FUNC_SET(conn, tls_connection_connected);
641
642 if (conn->failed) {
643 ua = fr_tls_session_fail_session(request, conn->tls_session);
644 } else {
645 ua = fr_tls_ticket_stateful_store_session(request, conn->tls_session);
646 }
647 TLS_CONNECTION_ERROR_RETURN;
648
649 return tls_connection_connected(request, conn);
650}
651
652/** Run handshake rounds until the handshakes finish.
653 *
654 * This function is largely a place-holder so that there is a stack
655 * frame which holds the current state. The request is woken up to
656 * process data, most of which happens in the async IO callback. But
657 * the frame is still processed. So we check the connection status
658 * here, and then either yield (if there's more handshaking to do), or
659 * go to the next state (on success or error).
660 */
661static unlang_action_t tls_connection_handshake(request_t *request, void *uctx)
662{
663 fr_tls_connection_t *conn = talloc_get_type_abort(uctx, fr_tls_connection_t);
665
666 conn->idle = false;
667
668 /*
669 * tls_connection_check() runs asynchronously in the IO
670 * callback, and changes the state we _want_ to be in.
671 * Check that here, and move to the next state if
672 * necessary.
673 */
674 if (conn->state == TLS_CONNECTION_TICKET) return tls_connection_ticket(request, conn);
675
676 /*
677 * Arm the repeat function before pushing anything else.
678 */
679 TLS_CONNECTION_FUNC_SET(conn, tls_connection_handshake);
680
681 /*
682 * No record is waiting for OpenSSL, yield until the next
683 * record arrives.
684 */
685 if (!conn->pending) {
686 conn->idle = true;
687 return UNLANG_ACTION_YIELD;
688 }
689
690 conn->pending = false;
691
692 /*
693 * fr_tls_session_async_handshake_push() pushes a new
694 * child frame onto the stack in order to process the
695 * SSL*. If that happens, we just tell the interpreter
696 * that we have a new child on the stack.
697 */
698 ua = fr_tls_session_async_handshake_push(request, conn->tls_session);
699 if (ua == UNLANG_ACTION_PUSHED_CHILD) return ua;
700
701 REDEBUG("(TLS) Failed pushing a TLS handshake round");
702 return tls_connection_error(request, conn);
703}
704
705/** Run `new session { ... }`, the first state of a connection
706 *
707 */
708static unlang_action_t tls_connection_new_session(request_t *request, void *uctx)
709{
710 fr_tls_connection_t *conn = talloc_get_type_abort(uctx, fr_tls_connection_t);
712
713 /*
714 * A state is running, so the request is not idle. The
715 * idle flag is set again during a handshake, if the
716 * request needs to wait for more OpenSSL negotiation to
717 * finish.
718 */
719 conn->idle = false;
720 conn->state = TLS_CONNECTION_HANDSHAKE;
721
722 if (conn->tls_session->conf->new_session) {
723 fr_assert(conn->tls_session->conf->virtual_server);
724
725 TLS_CONNECTION_FUNC_SET(conn, tls_connection_handshake);
726
727 ua = fr_tls_new_session_push(request, conn->tls_session->conf);
728 TLS_CONNECTION_ERROR_RETURN;
729 }
730
731 return tls_connection_handshake(request, conn);
732}
733
734/** Return how many bytes should be written.
735 *
736 * For stream sockets, return all of the data in the buffer.
737 *
738 * For datagram sockets, return the length of the first datagram.
739 *
740 * @param[in] conn to read.
741 * @return the number of octets to write, or 0 when nothing is waiting.
742 */
743static size_t tls_connection_write_len(fr_tls_connection_t *conn)
744{
745 fr_tls_session_t *tls_session = conn->tls_session;
746
747 if (tls_session->socket_type == SOCK_DGRAM) return fr_tls_session_datagram_len(tls_session);
748
749 return fr_dbuff_remaining(tls_session->dirty_out);
750}
751
752/** Allocate a connection
753 *
754 * The connection owns its own timer list, taken from `tl`, which the DTLS
755 * retransmission timer hangs off. Every connection gets one, not only a
756 * datagram connection, because the handshake has timers which are nothing to
757 * do with the transport: a TLS 1.3 peer which owes us a session ticket is
758 * waited for on a timer too.
759 *
760 * The caller sets `uctx` before the connection runs. The three callbacks
761 * read `conn->uctx` rather than taking a context argument of their own.
762 *
763 * @param[in] ctx to allocate the connection in.
764 * @param[in] tl to allocate the connection's timer sub-list from.
765 * @param[in] write called to write octets to the peer.
766 * @param[in] connected called once the connection can carry application data.
767 * @param[in] close called when the connection ends.
768 * @return
769 * - the connection on success.
770 * - NULL on failure.
771 */
772fr_tls_connection_t *fr_tls_connection_alloc(TALLOC_CTX *ctx, fr_timer_list_t *tl,
773 ssize_t (*write)(fr_tls_connection_t *conn,
774 uint8_t const *data, size_t size),
775 void (*connected)(fr_tls_connection_t *conn),
776 void (*close)(fr_tls_connection_t *conn))
777{
778 fr_tls_connection_t *conn;
779
780 conn = talloc_zero(ctx, fr_tls_connection_t);
781 if (!conn) return NULL;
782
783 conn->tl = fr_timer_list_lst_alloc(conn, tl);
784 if (!conn->tl) {
785 talloc_free(conn);
786 return NULL;
787 }
788
789 conn->write = write;
790 conn->connected = connected;
791 conn->close = close;
792
793 return conn;
794}
795
796/** Run the connection's state machine, then do the connection's IO
797 *
798 * This is the only function that is pushed onto the interpreter stack.
799 *
800 * This connection code runs its own state machine, which calls fr_tls_session_*() functions. That state
801 * machine reads or writes data to the dbuffs, and suggests that we yield / calculate_result / etc. However,
802 * the state machine doesn't do IO.
803
804 * Once the dbuffs have data, fr_tls_connection_process() has to run. The interpreter doesn't have a
805 * "post-yield" hook, so we have to run the entire connection state machine ourselves. We can then do
806 * whatever work is necessary for the connection, and then do the suggested yield / calculate_result, etc.
807 *
808 * @param[in] request the connection runs under.
809 * @param[in] uctx the #fr_tls_connection_t.
810 * @return
811 * - UNLANG_ACTION_PUSHED_CHILD a policy section is running.
812 * - UNLANG_ACTION_YIELD waiting for the peer.
813 * - UNLANG_ACTION_CALCULATE_RESULT the connection has finished.
814 */
815static unlang_action_t tls_connection_frame_process(request_t *request, void *uctx)
816{
817 fr_tls_connection_t *conn = talloc_get_type_abort(uctx, fr_tls_connection_t);
819
820 /*
821 * Re-arm ourselves every time through the interpreter loop.
822 */
823 if (unlang_function_repeat_set(request, tls_connection_frame_process) < 0) {
824 return UNLANG_ACTION_FAIL;
825 }
826
827 /*
828 * The connection's state machine has run out of states, we must be done.
829 */
830 if (!conn->process) return UNLANG_ACTION_CALCULATE_RESULT;
831
832 conn->in_frame = true;
833
834again:
835 conn->wake_pending = false;
836
837 ua = conn->process(request, conn);
838
839 switch (ua) {
840 /*
841 * A policy section is running as a real unlang child. The pending TLS data can wait
842 * until that section finishes and the interpeter returns to us here.
843 */
845 conn->in_frame = false;
846 return ua;
847
848 /*
849 * The connection is about to wait for the peer. Write the pending TLS data, and
850 * re-check the connection, before waiting for the peer.
851 */
853 fr_tls_connection_process(conn);
854
855 /*
856 * fr_tls_connection_process() re-checks the connection, and that check can result in
857 * more handshake data, or a connection failure. Both states ask for the state machine
858 * to run again. If there's a wake pending, we just loop here, rather than taking
859 * another bounce through the interpreter.
860 */
861 if (conn->wake_pending) goto again;
862
863 conn->in_frame = false;
864 return UNLANG_ACTION_YIELD;
865
866 default:
867 conn->in_frame = false;
868 return ua;
869 }
870}
871
872/** Push the connection frame onto the request's stack
873 *
874 * Run the interpreter once after fr_tls_connection_push() returns, so that
875 * the connection frame yields. unlang_interpret_mark_runnable() acts only on
876 * a yielded frame, and so fr_tls_connection_wake() does nothing until the
877 * connection frame has yielded at least once.
878 *
879 * @param[in] conn to run. `conn->request` must be set, and `conn` must be
880 * a talloc chunk, as `conn->name` is allocated from it.
881 * @return
882 * - 0 on success.
883 * - -1 on failure.
884 */
885int fr_tls_connection_push(fr_tls_connection_t *conn)
886{
887 /*
888 * Give the connection a name for the log, so that nothing has
889 * to check for NULL before printing one. The application knows
890 * what identifies a connection and the library does not, so a
891 * name the application set is left alone.
892 *
893 * The name is a child of the connection, so it cannot outlive
894 * the connection, and an application which sets its own name
895 * frees this one first.
896 */
897 if (!conn->name) MEM(conn->name = talloc_strdup(conn, "(TLS)"));
898
899 /*
900 * The connection's own state machine starts at `new session`.
901 * The interpreter is told only about the frame which runs that
902 * machine.
903 */
904 TLS_CONNECTION_FUNC_SET(conn, tls_connection_new_session);
905
906 return unlang_function_push(conn->request,
907 tls_connection_frame_process,
908 tls_connection_frame_process,
909 NULL, FR_SIGNAL_NONE, UNLANG_TOP_FRAME, conn);
910}
911
912/** A TLS record is available, so wake up the connection to process it.
913 *
914 * The connection frame yields between rounds, so we need to mark the
915 * request as runnable in order to process the data through the
916 * interpreter. We can't run the interpreter from an asynchronous IO
917 * callback!
918 *
919 * @param[in] conn to wake.
920 */
921void fr_tls_connection_wake(fr_tls_connection_t *conn)
922{
923 conn->pending = true;
924
925 tls_connection_request_wake(conn);
926}
927
928/** Hand octets which arrived on the connection to OpenSSL.
929 *
930 * The caller reads from whatever transport the caller uses, and
931 * passes the data to OpenSSL. Nothing else in the TLS library
932 * (currentl) reads a socket, so the transport stays entirely with the
933 * caller. EAP does the same thing, except the contents are taken
934 * from the EAP packets.
935 *
936 * The data doesn't have to be an entire record, and can be more than
937 * one record. The application doesn't parse TLS, it just reads raw
938 * data and hands it to OpenSSL. OpenSSL reads some or all of it.
939 * Any unread data is left in the buffer, as it generally means we
940 * read an incomplete TLS record from the wire.
941 *
942 * We therefore append the received data to the buffer. The
943 * "into_openssl" buffer size is capped at FR_TLS_MAX_PACKET_SIZE, so
944 * if a caller tries to overfill the buffer, this function marks the
945 * connection as failed.
946 *
947 * @todo - perhaps make the "into_ssl" dbuff extensable, but with
948 * limits. See tls_session_alloc() for caveats.
949 *
950 * @param[in] conn the octets arrived on.
951 * @param[in] data which arrived.
952 * @param[in] data_len how many octets arrived. Must be greater than zero.
953 */
954void fr_tls_connection_recv(fr_tls_connection_t *conn, uint8_t const *data, size_t data_len)
955{
956 fr_tls_session_t *tls_session = conn->tls_session;
957 request_t *request = conn->request;
958
959 RDEBUG3("(TLS) Read %zu bytes from the connection", data_len);
960
961 if (fr_dbuff_in_memcpy_partial(tls_session->dirty_in, data, data_len) != data_len) {
962 REDEBUG("(TLS) Failed buffering %zu bytes of TLS record data", data_len);
963 fr_tls_session_error_alert(request, tls_session,
964 FR_ERROR_VALUE_RECORD_TOO_LARGE, SSL_AD_RECORD_OVERFLOW);
965 error:
966 fr_tls_connection_failed(conn, TLS_CONNECTION_FAIL_TLS);
967 return;
968 }
969
970 /*
971 * Pushing a handshake round after the handshake has finished is
972 * a logic error. See src/lib/tls/session.c. Application data
973 * is not handled yet, so a record arriving now is an error.
974 */
975 if (fr_tls_session_is_init_finished(tls_session)) {
976 REDEBUG("(TLS) Received %zu bytes of application data, which is not supported", data_len);
977 fr_tls_session_error_alert(request, tls_session,
978 FR_ERROR_VALUE_RECORD_AFTER_HANDSHAKE, SSL_AD_UNEXPECTED_MESSAGE);
979 goto error;
980 }
981
982 /*
983 * Hand the round over to the connection frame, which is sitting
984 * yielded, waiting for exactly that record.
985 */
986 fr_tls_connection_wake(conn);
987}
988
989/** Write all pending data to the peer.
990 *
991 * Runs the application `write()` callback with the data. For stream sockets, we try to write all of the data
992 * in one swell foop. For datagram sockets, we write the data one datagram at a time
993 *
994 * A write which reports zero means it wrote no data. All data left stays in the buffer, and the application
995 * calls us again when the socket becomes writable.
996 *
997 * @param[in] conn to write from.
998 * @return
999 * - 0 on success, including when the socket filled.
1000 * - -1 if the application's write failed.
1001 */
1002int fr_tls_connection_write(fr_tls_connection_t *conn)
1003{
1004 size_t size;
1005
1006 while ((size = tls_connection_write_len(conn)) > 0) {
1007 uint8_t const *data = fr_dbuff_current(conn->tls_session->dirty_out);
1008 ssize_t slen;
1009
1010 slen = conn->write(conn, data, size);
1011 if (slen < 0) return -1;
1012
1013 /*
1014 * The socket is full. Nothing was lost, so this is not a failure.
1015 */
1016 if (slen == 0) break;
1017
1018 fr_assert((size_t) slen <= size);
1019
1020 /*
1021 * Datagrams are either fully written, or not at all.
1022 */
1023 fr_assert((conn->tls_session->socket_type != SOCK_DGRAM) || ((size_t) slen == size));
1024
1025 fr_dbuff_advance(conn->tls_session->dirty_out, (size_t) slen);
1026
1027 /*
1028 * The cursor has passed this datagram, so the length
1029 * which described it is no longer needed.
1030 */
1031 if (conn->tls_session->socket_type == SOCK_DGRAM) fr_tls_session_datagram_sent(conn->tls_session);
1032 }
1033
1034 return 0;
1035}
1036
1037/** Write out any pending records, then re-check the handshake state
1038 *
1039 * Write the data to the IO layer, then check if the connection is
1040 * errored, OK, finished, etc. We gave to write the data to the IO
1041 * layer so that any TLS alerts, close-notify, etc. will reach the
1042 * peer.
1043 *
1044 * @param[in] conn to process.
1045 */
1046void fr_tls_connection_process(fr_tls_connection_t *conn)
1047{
1048 /*
1049 * fr_tls_connection_recv() refuses some records without handing them to a handshake round at
1050 * all, so for those there is no round to put the closing record into the outgoing buffer. Do
1051 * it here instead, before the write below, so the peer gets the record rather than a socket
1052 * which stops answering.
1053 *
1054 * Only a failure inside TLS reaches this. TLS_CONNECTION_FAIL_SYSCALL and
1055 * TLS_CONNECTION_FAIL_APPLICATION both mean the socket has been closed, and we can't write a
1056 * close notify.
1057 *
1058 * Any error inside of a handshake has been handled by OpenSSL, and this call does nothing more.
1059 */
1060 if (conn->failed == TLS_CONNECTION_FAIL_TLS) fr_tls_session_close_send(conn->request, conn->tls_session);
1061
1062 /*
1063 * Record a failure on error, but keep processing the TLS state machine, so that we can run `fail
1064 * connection`.
1065 */
1066 if (fr_tls_connection_write(conn) < 0) fr_tls_connection_failed(conn, TLS_CONNECTION_FAIL_APPLICATION);
1067
1068 /*
1069 * OpenSSL knows when it next wants attention, and the answer
1070 * changes after every round, so the timer is updated after
1071 * every round. fr_dtls_timer_update() does nothing when the
1072 * connection has no timer list, which is how a stream
1073 * connection says it has nothing to time.
1074 */
1075 fr_dtls_timer_update(conn);
1076
1077 tls_connection_check(conn);
1078}
1079#endif /* WITH_TLS */
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
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
Definition action.h:38
@ UNLANG_ACTION_YIELD
Temporarily pause execution until an event occurs.
Definition action.h:42
static uint8_t request[4]
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:245
#define UNUSED
Definition build.h:415
#define NUM_ELEMENTS(_t)
Definition build.h:437
#define fr_dbuff_advance(_dbuff_or_marker, _len)
Advance 'current' position in dbuff or marker by _len bytes.
Definition dbuff.h:1121
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
Definition dbuff.h:963
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
Definition dbuff.h:795
#define fr_dbuff_in_memcpy_partial(_out, _in, _inlen)
Copy at most _inlen bytes into the dbuff.
Definition dbuff.h:1491
#define MEM(x)
Definition debug.h:38
#define unlang_function_repeat_set(_request, _repeat)
Set a new repeat function for an existing function frame.
Definition function.h:110
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
Definition function.h:181
talloc_free(hp)
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
Definition interpret.c:2008
#define UNLANG_TOP_FRAME
Definition interpret.h:36
#define RDEBUG3(fmt,...)
Definition log.h:360
long int ssize_t
unsigned char uint8_t
#define fr_assert(_expr)
Definition rad_assert.h:37
#define REDEBUG(fmt,...)
#define RDEBUG2(fmt,...)
#define INFO(fmt,...)
Definition radict.c:67
@ FR_SIGNAL_NONE
No signals.
Definition signal.h:39
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:804
An element in a table indexed by numeric value.
Definition table.h:92
#define talloc_strdup(_ctx, _str)
Definition talloc.h:149
"server local" time.
Definition time.h:69
fr_timer_list_t * fr_timer_list_lst_alloc(TALLOC_CTX *ctx, fr_timer_list_t *parent)
Allocate a new lst based timer list.
Definition timer.c:1262
An event timer list.
Definition timer.c:49
#define FR_TIMER_DELETE(_ev_p)
Definition timer.h:105
#define fr_timer_in(...)
Definition timer.h:87
static fr_slen_t data
Definition value.h:1366