The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
session.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: 007452fbb92a5fcec7c67dd80e6178b2784b7f84 $
19  *
20  * @file tls/session.c
21  * @brief Initialise OpenSSL sessions, and read/write data to/from them.
22  *
23  * @copyright 2001 hereUare Communications, Inc. (raghud@hereuare.com)
24  * @copyright 2003 Alan DeKok (aland@freeradius.org)
25  * @copyright 2006-2016 The FreeRADIUS server project
26  */
27 #ifdef WITH_TLS
28 #define LOG_PREFIX "tls"
29 
30 #include <freeradius-devel/server/pair.h>
31 #include <freeradius-devel/server/log.h>
32 
33 #include <freeradius-devel/util/debug.h>
34 #include <freeradius-devel/util/base16.h>
35 #include <freeradius-devel/util/misc.h>
36 #include <freeradius-devel/util/pair_legacy.h>
37 
38 #include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
39 
40 #include <freeradius-devel/unlang/interpret.h>
41 
42 #include <sys/stat.h>
43 #include <ctype.h>
44 #include <fcntl.h>
45 
46 #include "attrs.h"
47 #include "base.h"
48 #include "log.h"
49 
50 #include <openssl/x509v3.h>
51 #include <openssl/ssl.h>
52 
53 static char const *tls_version_str[] = {
54  [SSL2_VERSION] = "SSL 2.0",
55  [SSL3_VERSION] = "SSL 3.0",
56  [TLS1_VERSION] = "TLS 1.0",
57 #ifdef TLS1_1_VERSION
58  [TLS1_1_VERSION] = "TLS 1.1",
59 #endif
60 #ifdef TLS1_2_VERSION
61  [TLS1_2_VERSION] = "TLS 1.2",
62 #endif
63 #ifdef TLS1_3_VERSION
64  [TLS1_3_VERSION] = "TLS 1.3",
65 #endif
66 #ifdef TLS1_4_VERSION
67  [TLS1_4_VERSION] = "TLS 1.4",
68 #endif
69 };
70 
71 static char const *tls_content_type_str[] = {
72  [SSL3_RT_CHANGE_CIPHER_SPEC] = "change_cipher_spec",
73  [SSL3_RT_ALERT] = "alert",
74  [SSL3_RT_HANDSHAKE] = "handshake",
75  [SSL3_RT_APPLICATION_DATA] = "application_data",
76 #ifdef SSL3_RT_HEADER
77  [SSL3_RT_HEADER] = "header",
78 #endif
79 #ifdef SSL3_RT_INNER_CONTENT_TYPE
80  [SSL3_RT_INNER_CONTENT_TYPE] = "inner_content_type",
81 #endif
82 };
83 
84 static char const *tls_alert_description_str[] = {
85  [SSL3_AD_CLOSE_NOTIFY] = "close_notify",
86  [SSL3_AD_UNEXPECTED_MESSAGE] = "unexpected_message",
87  [SSL3_AD_BAD_RECORD_MAC] = "bad_record_mac",
88  [TLS1_AD_DECRYPTION_FAILED] = "decryption_failed",
89  [TLS1_AD_RECORD_OVERFLOW] = "record_overflow",
90  [SSL3_AD_DECOMPRESSION_FAILURE] = "decompression_failure",
91  [SSL3_AD_HANDSHAKE_FAILURE] = "handshake_failure",
92  [SSL3_AD_BAD_CERTIFICATE] = "bad_certificate",
93  [SSL3_AD_UNSUPPORTED_CERTIFICATE] = "unsupported_certificate",
94  [SSL3_AD_CERTIFICATE_REVOKED] = "certificate_revoked",
95  [SSL3_AD_CERTIFICATE_EXPIRED] = "certificate_expired",
96  [SSL3_AD_CERTIFICATE_UNKNOWN] = "certificate_unknown",
97  [SSL3_AD_ILLEGAL_PARAMETER] = "illegal_parameter",
98  [TLS1_AD_UNKNOWN_CA] = "unknown_ca",
99  [TLS1_AD_ACCESS_DENIED] = "access_denied",
100  [TLS1_AD_DECODE_ERROR] = "decode_error",
101  [TLS1_AD_DECRYPT_ERROR] = "decrypt_error",
102  [TLS1_AD_EXPORT_RESTRICTION] = "export_restriction",
103  [TLS1_AD_PROTOCOL_VERSION] = "protocol_version",
104  [TLS1_AD_INSUFFICIENT_SECURITY] = "insufficient_security",
105  [TLS1_AD_INTERNAL_ERROR] = "internal_error",
106  [TLS1_AD_USER_CANCELLED] = "user_cancelled",
107  [TLS1_AD_NO_RENEGOTIATION] = "no_renegotiation",
108 #ifdef TLS13_AD_MISSING_EXTENSION
109  [TLS13_AD_MISSING_EXTENSION] = "missing_extension",
110 #endif
111 #ifdef TLS13_AD_CERTIFICATE_REQUIRED
112  [TLS13_AD_CERTIFICATE_REQUIRED] = "certificate_required",
113 #endif
114 #ifdef TLS1_AD_UNSUPPORTED_EXTENSION
115  [TLS1_AD_UNSUPPORTED_EXTENSION] = "unsupported_extension",
116 #endif
117 #ifdef TLS1_AD_CERTIFICATE_UNOBTAINABLE
118  [TLS1_AD_CERTIFICATE_UNOBTAINABLE] = "certificate_unobtainable",
119 #endif
120 #ifdef TLS1_AD_UNRECOGNIZED_NAME
121  [TLS1_AD_UNRECOGNIZED_NAME] = "unrecognised_name",
122 #endif
123 #ifdef TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
124  [TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE] = "bad_certificate_status_response",
125 #endif
126 #ifdef TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
127  [TLS1_AD_BAD_CERTIFICATE_HASH_VALUE] = "bad_certificate_hash_value",
128 #endif
129 #ifdef TLS1_AD_UNKNOWN_PSK_IDENTITY
130  [TLS1_AD_UNKNOWN_PSK_IDENTITY] = "unknown_psk_identity",
131 #endif
132 #ifdef TLS1_AD_NO_APPLICATION_PROTOCOL
133  [TLS1_AD_NO_APPLICATION_PROTOCOL] = "no_application_protocol",
134 #endif
135 };
136 
137 static char const *tls_handshake_type_str[] = {
138  [SSL3_MT_HELLO_REQUEST] = "hello_request",
139  [SSL3_MT_CLIENT_HELLO] = "client_hello",
140  [SSL3_MT_SERVER_HELLO] = "server_hello",
141 #ifdef SSL3_MT_NEWSESSION_TICKET
142  [SSL3_MT_NEWSESSION_TICKET] = "new_session_ticket",
143 #endif
144 #ifdef SSL3_MT_END_OF_EARLY_DATA
145  [SSL3_MT_END_OF_EARLY_DATA] = "end_of_early_data",
146 #endif
147 #ifdef SSL3_MT_ENCRYPTED_EXTENSIONS
148  [SSL3_MT_ENCRYPTED_EXTENSIONS] = "encrypted_extensions",
149 #endif
150  [SSL3_MT_CERTIFICATE] = "certificate",
151  [SSL3_MT_SERVER_KEY_EXCHANGE] = "server_key_exchange",
152  [SSL3_MT_CERTIFICATE_REQUEST] = "certificate_request",
153  [SSL3_MT_SERVER_DONE] = "server_hello_done",
154  [SSL3_MT_CERTIFICATE_VERIFY] = "certificate_verify",
155  [SSL3_MT_CLIENT_KEY_EXCHANGE] = "client_key_exchange",
156  [SSL3_MT_FINISHED] = "finished",
157 #ifdef SSL3_MT_CERTIFICATE_URL
158  [SSL3_MT_CERTIFICATE_URL] = "certificate_url",
159 #endif
160 #ifdef SSL3_MT_CERTIFICATE_STATUS
161  [SSL3_MT_CERTIFICATE_STATUS] = "certificate_status",
162 #endif
163 #ifdef SSL3_MT_SUPPLEMENTAL_DATA
164  [SSL3_MT_SUPPLEMENTAL_DATA] = "supplemental_data",
165 #endif
166 #ifdef SSL3_MT_KEY_UPDATE
167  [SSL3_MT_KEY_UPDATE] = "key_update",
168 #endif
169 #ifdef SSL3_MT_NEXT_PROTO
170  [SSL3_MT_NEXT_PROTO] = "next_proto",
171 #endif
172 #ifdef SSL3_MT_MESSAGE_HASH
173  [SSL3_MT_MESSAGE_HASH] = "message_hash",
174 #endif
175 #ifdef DTLS1_MT_HELLO_VERIFY_REQUEST
176  [DTLS1_MT_HELLO_VERIFY_REQUEST] = "hello_verify_request",
177 #endif
178 #ifdef SSL3_MT_CHANGE_CIPHER_SPEC
179  [SSL3_MT_CHANGE_CIPHER_SPEC] = "change_cipher_spec",
180 #endif
181 };
182 
183 /** Clear a record buffer
184  *
185  * @param record buffer to clear.
186  */
187 inline static void record_init(fr_tls_record_t *record)
188 {
189  record->used = 0;
190 }
191 
192 /** Destroy a record buffer
193  *
194  * @param record buffer to destroy clear.
195  */
196 inline static void record_close(fr_tls_record_t *record)
197 {
198  record->used = 0;
199 }
200 
201 /** Copy data to the intermediate buffer, before we send it somewhere
202  *
203  * @param[in] record buffer to write to.
204  * @param[in] in data to write.
205  * @param[in] inlen Length of data to write.
206  * @return the amount of data written to the record buffer.
207  */
208 inline static unsigned int record_from_buff(fr_tls_record_t *record, void const *in, unsigned int inlen)
209 {
210  unsigned int added = FR_TLS_MAX_RECORD_SIZE - record->used;
211 
212  if (added > inlen) added = inlen;
213  if (added == 0) return 0;
214 
215  memcpy(record->data + record->used, in, added);
216  record->used += added;
217 
218  return added;
219 }
220 
221 /** Take data from the buffer, and give it to the caller
222  *
223  * @param[in] record buffer to read from.
224  * @param[out] out where to write data from record buffer.
225  * @param[in] outlen The length of the output buffer.
226  * @return the amount of data written to the output buffer.
227  */
228 inline static unsigned int record_to_buff(fr_tls_record_t *record, void *out, unsigned int outlen)
229 {
230  unsigned int taken = record->used;
231 
232  if (taken > outlen) taken = outlen;
233  if (taken == 0) return 0;
234  if (out) memcpy(out, record->data, taken);
235 
236  record->used -= taken;
237 
238  /*
239  * This is pretty bad...
240  */
241  if (record->used > 0) memmove(record->data, record->data + taken, record->used);
242 
243  return taken;
244 }
245 
246 /** Return the static private key password we have configured
247  *
248  * @param[out] buf Where to write the password to.
249  * @param[in] size The length of buf.
250  * @param[in] rwflag
251  * - 0 if password used for decryption.
252  * - 1 if password used for encryption.
253  * @param[in] u The static password.
254  * @return
255  * - 0 on error.
256  * - >0 on success (the length of the password).
257  */
258 int fr_tls_session_password_cb(char *buf, int size, int rwflag UNUSED, void *u)
259 {
260  size_t len;
261 
262  /*
263  * We do this instead of not registering the callback
264  * to ensure OpenSSL doesn't try and read a password
265  * from stdin (causes server to block).
266  */
267  if (!u) {
268  ERROR("Private key encrypted but no private_key_password configured");
269  return 0;
270  }
271 
272  len = strlcpy(buf, (char *)u, size);
273  if (len > (size_t)size) {
274  ERROR("Password too long. Maximum length is %i bytes", size - 1);
275  return 0;
276  }
277 
278  return len;
279 }
280 
281 #ifdef PSK_MAX_IDENTITY_LEN
282 /** Verify the PSK identity contains no reserved chars
283  *
284  * @param identity to check.
285  * @return
286  * - true identity does not contain reserved chars.
287  * - false identity contains reserved chars.
288  */
289 static bool session_psk_identity_is_safe(const char *identity)
290 {
291  char c;
292 
293  if (!identity) return true;
294 
295  while ((c = *(identity++)) != '\0') {
296  if (isalpha((uint8_t) c) || isdigit((uint8_t) c) || isspace((uint8_t) c) ||
297  (c == '@') || (c == '-') || (c == '_') || (c == '.')) {
298  continue;
299  }
300 
301  return false;
302  }
303 
304  return true;
305 }
306 
307 /** Determine the PSK to use for an outgoing connection
308  *
309  * @param[in] ssl session.
310  * @param[in] identity The identity of the PSK to search for.
311  * @param[out] psk Where to write the PSK we found (if any).
312  * @param[in] max_psk_len The length of the buffer provided for PSK.
313  * @return
314  * - 0 if no PSK matching identity was found.
315  * - >0 if a PSK matching identity was found (the length of bytes written to psk).
316  */
317 unsigned int fr_tls_session_psk_client_cb(SSL *ssl, UNUSED char const *hint,
318  char *identity, unsigned int max_identity_len,
319  unsigned char *psk, unsigned int max_psk_len)
320 {
321  unsigned int psk_len;
322  fr_tls_conf_t *conf;
323 
324  conf = (fr_tls_conf_t *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF);
325  if (!conf) return 0;
326 
327  psk_len = strlen(conf->psk_password);
328  if (psk_len > (2 * max_psk_len)) return 0;
329 
330  strlcpy(identity, conf->psk_identity, max_identity_len);
331 
332  return fr_base16_decode(NULL,
333  &FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len),
334  &FR_SBUFF_IN(conf->psk_password, (size_t)psk_len), false);
335 }
336 
337 /** Determine the PSK to use for an incoming connection
338  *
339  * @param[in] ssl session.
340  * @param[in] identity The identity of the PSK to search for.
341  * @param[out] psk Where to write the PSK we found (if any).
342  * @param[in] max_psk_len The length of the buffer provided for PSK.
343  * @return
344  * - 0 if no PSK matching identity was found.
345  * - >0 if a PSK matching identity was found (the length of bytes written to psk).
346  */
347 unsigned int fr_tls_session_psk_server_cb(SSL *ssl, const char *identity,
348  unsigned char *psk, unsigned int max_psk_len)
349 {
350  size_t psk_len = 0;
351  fr_tls_conf_t *conf;
352  request_t *request;
353 
354  conf = (fr_tls_conf_t *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF);
355  if (!conf) return 0;
356 
357  request = fr_tls_session_request(ssl);
358  if (request && conf->psk_query) {
359  size_t hex_len;
360  fr_pair_t *vp;
361  char buffer[2 * PSK_MAX_PSK_LEN + 4]; /* allow for too-long keys */
362 
363  /*
364  * The passed identity is weird. Deny it.
365  */
366  if (!session_psk_identity_is_safe(identity)) {
367  RWDEBUG("Invalid characters in PSK identity %s", identity);
368  return 0;
369  }
370 
372  if (fr_pair_value_from_str(vp, identity, strlen(identity), NULL, true) < 0) {
373  RPWDEBUG2("Failed parsing TLS PSK Identity");
374  talloc_free(vp);
375  return 0;
376  }
377 
378  hex_len = xlat_eval(buffer, sizeof(buffer), request, conf->psk_query, NULL, NULL);
379  if (!hex_len) {
380  RWDEBUG("PSK expansion returned an empty string.");
381  return 0;
382  }
383 
384  /*
385  * The returned key is truncated at MORE than
386  * OpenSSL can handle. That way we can detect
387  * the truncation, and complain about it.
388  */
389  if (hex_len > (2 * max_psk_len)) {
390  RWDEBUG("Returned PSK is too long (%u > %u)", (unsigned int) hex_len, 2 * max_psk_len);
391  return 0;
392  }
393 
394  /*
395  * Leave the TLS-PSK-Identity in the request, and
396  * convert the expansion from printable string
397  * back to hex.
398  */
399  return fr_base16_decode(NULL,
400  &FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len),
401  &FR_SBUFF_IN(buffer, hex_len), false);
402  }
403 
404  if (!conf->psk_identity) {
405  DEBUG("No static PSK identity set. Rejecting the user");
406  return 0;
407  }
408 
409  /*
410  * No request_t, or no dynamic query. Just look for a
411  * static identity.
412  */
413  if (strcmp(identity, conf->psk_identity) != 0) {
414  ERROR("Supplied PSK identity %s does not match configuration. Rejecting.",
415  identity);
416  return 0;
417  }
418 
419  psk_len = strlen(conf->psk_password);
420  if (psk_len > (2 * max_psk_len)) return 0;
421 
422  return fr_base16_decode(NULL,
423  &FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len),
424  &FR_SBUFF_IN(conf->psk_password, psk_len), false);
425 }
426 #endif /* PSK_MAX_IDENTITY_LEN */
427 
429 DIAG_OFF(used-but-marked-unused) /* Fix spurious warnings for sk_ macros */
430 /** Record session state changes
431  *
432  * Called by OpenSSL whenever the session state changes, an alert is received or an error occurs.
433  *
434  * @param[in] ssl session.
435  * @param[in] where Which context the callback is being called in.
436  * See https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_info_callback.html
437  * for additional info.
438  * @param[in] ret 0 if an error occurred, or the alert type if an alert was received.
439  */
440 void fr_tls_session_info_cb(SSL const *ssl, int where, int ret)
441 {
442  char const *role, *state;
443  request_t *request = SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_REQUEST);
444 
445  if ((where & ~SSL_ST_MASK) & SSL_ST_CONNECT) {
446  role = "Client ";
447  } else if (((where & ~SSL_ST_MASK)) & SSL_ST_ACCEPT) {
448  role = "Server ";
449  } else {
450  role = "";
451  }
452 
453  state = SSL_state_string_long(ssl);
454  state = state ? state : "<INVALID>";
455 
456  if ((where & SSL_CB_LOOP) || (where & SSL_CB_HANDSHAKE_START) || (where & SSL_CB_HANDSHAKE_DONE)) {
458  char const *abbrv = SSL_state_string(ssl);
459  size_t len;
460 
461  /*
462  * Trim crappy OpenSSL state strings...
463  */
464  len = strlen(abbrv);
465  if ((len > 1) && (abbrv[len - 1] == ' ')) len--;
466 
467  ROPTIONAL(RDEBUG3, DEBUG3, "Handshake state [%.*s] - %s%s", (int)len, abbrv, role, state);
468 
469 #ifdef OPENSSL_NO_SSL_TRACE
470  {
471  STACK_OF(SSL_CIPHER) *server_ciphers;
472  STACK_OF(SSL_CIPHER) *client_ciphers;
473 
474  /*
475  * After a ClientHello, list all the proposed ciphers
476  * from the client.
477  *
478  * Only do this if we don't have SSL_trace() as
479  * SSL_trace() prints this information and we don't
480  * want to duplicate it.
481  */
482  if (SSL_get_state(ssl) == TLS_ST_SR_CLNT_HELLO &&
483  (client_ciphers = SSL_get_client_ciphers(ssl))) {
484  int i;
485  int num_ciphers;
486  const SSL_CIPHER *this_cipher;
487 
488  server_ciphers = SSL_get_ciphers(ssl);
489  /*
490  * These are printed on startup, so not usually
491  * required.
492  */
493  ROPTIONAL(RDEBUG4, DEBUG4, "Our preferred ciphers (by priority)");
495  if (request) RINDENT();
496  num_ciphers = sk_SSL_CIPHER_num(server_ciphers);
497  for (i = 0; i < num_ciphers; i++) {
498  this_cipher = sk_SSL_CIPHER_value(server_ciphers, i);
499  ROPTIONAL(RDEBUG4, DEBUG4, "[%i] %s", i, SSL_CIPHER_get_name(this_cipher));
500  }
501  if (request) REXDENT();
502  }
503 
504  /*
505  * Print information about the client's
506  * handshake message.
507  */
509  ROPTIONAL(RDEBUG3, DEBUG3, "Client's preferred ciphers (by priority)");
510  if (request) RINDENT();
511  num_ciphers = sk_SSL_CIPHER_num(client_ciphers);
512  for (i = 0; i < num_ciphers; i++) {
513  this_cipher = sk_SSL_CIPHER_value(client_ciphers, i);
514  ROPTIONAL(RDEBUG3, DEBUG3, "[%i] %s", i, SSL_CIPHER_get_name(this_cipher));
515  }
516  if (request) REXDENT();
517  }
518  }
519  }
520 # endif
521  } else {
522  ROPTIONAL(RDEBUG2, DEBUG2, "Handshake state - %s%s (%i)", role, state, SSL_get_state(ssl));
523  }
524  return;
525  }
526 
527  if (where & SSL_CB_ALERT) {
528  if ((ret & 0xff) == SSL_AD_CLOSE_NOTIFY) return;
529 
530  /*
531  * We got an alert...
532  */
533  if (where & SSL_CB_READ) {
534  fr_pair_t *vp;
535 
536  ROPTIONAL(REDEBUG, ERROR, "Client sent %s TLS alert (%i) - %s", SSL_alert_type_string_long(ret),
537  ret & 0xff, SSL_alert_desc_string_long(ret));
538 
539  /*
540  * Offer helpful advice... Should be expanded.
541  */
542  switch (ret & 0xff) {
543  case TLS1_AD_UNKNOWN_CA:
544  REDEBUG("Verify the client has a copy of the server's Certificate "
545  "Authority (CA) installed, and trusts that CA");
546  break;
547 
548  default:
549  break;
550  }
551 
553  vp->vp_uint8 = ret & 0xff;
554  ROPTIONAL(RDEBUG2, DEBUG2, "&TLS-Client-Error-Code := %pV", &vp->data);
555  /*
556  * We're sending the client an alert.
557  */
558  } else {
559  ROPTIONAL(REDEBUG, ERROR, "Sending client %s TLS alert (%i) - %s",
560  SSL_alert_type_string_long(ret), ret & 0xff, SSL_alert_desc_string_long(ret));
561 
562  /*
563  * Offer helpful advice... Should be expanded.
564  */
565  switch (ret & 0xff) {
566  case TLS1_AD_PROTOCOL_VERSION:
567  ROPTIONAL(REDEBUG, ERROR, "Client requested a TLS protocol version that is not "
568  "enabled or not supported. Upgrade FreeRADIUS + OpenSSL to their latest "
569  "versions and/or adjust 'tls_max_version'/'tls_min_version' if you want "
570  "authentication to succeed");
571  break;
572 
573  default:
574  break;
575  }
576  }
577  return;
578  }
579 
580  if (where & SSL_CB_EXIT) {
581  if (ret == 0) {
582  ROPTIONAL(REDEBUG, ERROR, "Handshake exit state %s%s", role, state);
583  return;
584  }
585 
586  if (ret < 0) {
587  if (SSL_want_read(ssl)) {
588  RDEBUG2("Need more data from client"); /* State same as previous call, don't print */
589  return;
590  }
591  ROPTIONAL(REDEBUG, ERROR, "Handshake exit state %s%s", role, state);
592  }
593  }
594 }
595 DIAG_ON(used-but-marked-unused)
597 
598 /** Print a message to the request or global log detailing handshake state
599  *
600  * @param[in] request The current #request_t.
601  * @param[in] tls_session The current TLS session.
602  */
603 static void session_msg_log(request_t *request, fr_tls_session_t *tls_session, uint8_t const *data, size_t data_len)
604 {
605  char const *version, *content_type;
606  char const *str_details1 = NULL;
607  char const *str_details2 = NULL;
608  char unknown_version[32];
609  char unknown_content_type[32];
610  char unknown_alert_level[32];
611  char unknown_alert_description[32];
612  char unknown_handshake_type[32];
613 
614  /*
615  * Don't print this out in the normal course of
616  * operations.
617  */
619 
620  if (((size_t)tls_session->info.version >= NUM_ELEMENTS(tls_version_str)) ||
621  !tls_version_str[tls_session->info.version]) {
622  snprintf(unknown_version, sizeof(unknown_version), "unknown_tls_version_0x%04x", tls_session->info.version);
623  version = unknown_version;
624  } else {
625  version = tls_version_str[tls_session->info.version];
626  }
627 
628  /*
629  * TLS 1.0, 1.1, 1.2 content types are the same as SSLv3
630  */
631  if (((size_t)tls_session->info.content_type >= NUM_ELEMENTS(tls_content_type_str)) ||
632  !tls_content_type_str[tls_session->info.content_type]) {
633  snprintf(unknown_content_type, sizeof(unknown_content_type),
634  "unknown_content_type_0x%04x", tls_session->info.content_type);
635  content_type = unknown_content_type;
636  } else {
637  content_type = tls_content_type_str[tls_session->info.content_type];
638  }
639 
640  if (tls_session->info.content_type == SSL3_RT_ALERT) {
641  if (tls_session->info.record_len == 2) {
642  switch (tls_session->info.alert_level) {
643  case SSL3_AL_WARNING:
644  str_details1 = "warning";
645  break;
646  case SSL3_AL_FATAL:
647  str_details1 = "fatal";
648  break;
649 
650  default:
651  snprintf(unknown_alert_level, sizeof(unknown_alert_level),
652  "unknown_alert_level_0x%04x", tls_session->info.alert_level);
653  str_details1 = unknown_alert_level;
654  break;
655  }
656 
657  if (((size_t)tls_session->info.alert_description >= NUM_ELEMENTS(tls_alert_description_str)) ||
658  !tls_alert_description_str[tls_session->info.alert_description]) {
659  snprintf(unknown_alert_description, sizeof(unknown_alert_description),
660  "unknown_alert_0x%04x", tls_session->info.alert_description);
661  str_details2 = unknown_alert_description;
662  } else {
663  str_details2 = tls_alert_description_str[tls_session->info.alert_description];
664  }
665  } else {
666  str_details1 = "unknown_alert_level";
667  str_details2 = "unknown_alert";
668  }
669  }
670 
671  if ((size_t)tls_session->info.content_type == SSL3_RT_HANDSHAKE) {
672  if (tls_session->info.record_len > 0) {
673  /*
674  * Range guard not needed due to size of array
675  * and underlying type.
676  */
677  if (!tls_handshake_type_str[tls_session->info.handshake_type]) {
678  snprintf(unknown_handshake_type, sizeof(unknown_handshake_type),
679  "unknown_handshake_type_0x%02x", tls_session->info.handshake_type);
680  str_details1 = unknown_handshake_type;
681  } else {
682  str_details1 = tls_handshake_type_str[tls_session->info.handshake_type];
683  }
684  }
685  }
686 
687  snprintf(tls_session->info.info_description, sizeof(tls_session->info.info_description),
688  "%s %s, %s[length %lu]%s%s%s%s",
689  tls_session->info.origin ? ">>> send" : "<<< recv",
690  version,
691  content_type,
692  (unsigned long)tls_session->info.record_len,
693  str_details1 ? ", " : "",
694  str_details1 ? str_details1 : "",
695  str_details2 ? ", " : "",
696  str_details2 ? str_details2 : "");
697 
698  /*
699  * Print out information about the record and print the
700  * data at higher debug levels.
701  */
703  ROPTIONAL(RHEXDUMP4, HEXDUMP4, data, data_len, "%s", tls_session->info.info_description);
704  } else {
705  ROPTIONAL(RDEBUG2, DEBUG2, "%s", tls_session->info.info_description);
706  }
707 }
708 
709 /** Record the progression of the TLS handshake
710  *
711  * This callback is called by OpenSSL whenever a protocol message relating to a handshake is sent
712  * or received.
713  *
714  * This function copies state information from the various arguments into the state->info
715  * structure of the #fr_tls_session_t, to allow us to track the progression of the handshake.
716  *
717  * @param[in] write_p
718  * - 0 when a message has been received.
719  * - 1 when a message has been sent.
720  *
721  * @param[in] msg_version The TLS version negotiated, should be one of:
722  * - TLS1_VERSION
723  * - TLS1_1_VERSION
724  * - TLS1_2_VERSION
725  * - TLS1_3_VERSION
726  *
727  * @param[in] content_type One of the contentType values defined for TLS:
728  * - SSL3_RT_CHANGE_CIPHER_SPEC (20)
729  * - SSL3_RT_ALERT (21)
730  * - SSL3_RT_HANDSHAKE (22)
731  * - TLS1_RT_HEARTBEAT (24)
732  *
733  * @param[in] inbuf The raw protocol message.
734  * @param[in] len Length of the raw protocol message.
735  * @param[in] ssl The SSL session.
736  * @param[in] arg The #fr_tls_session_t holding the SSL session.
737  */
738 void fr_tls_session_msg_cb(int write_p, int msg_version, int content_type,
739  void const *inbuf, size_t len,
740  SSL *ssl, void *arg)
741 {
742  uint8_t const *buf = inbuf;
743  fr_tls_session_t *tls_session = talloc_get_type_abort(arg, fr_tls_session_t);
744  request_t *request = fr_tls_session_request(tls_session->ssl);
745 
746  /*
747  * Mostly to check for memory corruption...
748  */
749  if (!fr_cond_assert(tls_session->ssl = ssl)) {
750  ROPTIONAL(REDEBUG, ERROR, "fr_tls_session_t and ssl arg do not match in fr_tls_session_msg_cb");
751  tls_session->invalid = true;
752  return;
753  }
754 
755  /*
756  * As per https://tools.ietf.org/html/rfc7568
757  *
758  * We explicitly disable SSLv2/v3, hence the asserts.
759  */
760 #ifdef SSL2_VERSION
761  if (!fr_cond_assert(msg_version != SSL2_VERSION)) {
762  ROPTIONAL(REDEBUG, ERROR, "Invalid version (SSLv2) in handshake");
763  tls_session->invalid = true;
764  return;
765  }
766 #endif
767 
768 #ifdef SSL3_VERSION
769  if (!fr_cond_assert(msg_version != SSL3_VERSION)) {
770  ROPTIONAL(REDEBUG, ERROR, "Invalid version (SSLv3) in handshake");
771  tls_session->invalid = true;
772  return;
773  }
774 #endif
775 
776  /*
777  * OpenSSL >= 1.0.2 calls this function with 'pseudo'
778  * content types. Which breaks our tracking of
779  * the SSL Session state.
780  */
781  if ((msg_version == 0) && (content_type > UINT8_MAX)) {
782  ROPTIONAL(REDEBUG4, DEBUG4, "Ignoring fr_tls_session_msg_cb call with pseudo content type %i, version %i",
783  content_type, msg_version);
784  return;
785  }
786 
787  if ((write_p != 0) && (write_p != 1)) {
788  ROPTIONAL(REDEBUG4, DEBUG4, "Ignoring fr_tls_session_msg_cb call with invalid write_p %d", write_p);
789  return;
790  }
791 
792  /*
793  * 0 - received (from peer)
794  * 1 - sending (to peer)
795  */
796  tls_session->info.origin = write_p;
797  tls_session->info.content_type = content_type;
798  tls_session->info.record_len = len;
799  tls_session->info.version = msg_version;
800  tls_session->info.initialized = true;
801 
802  switch (content_type) {
803  case SSL3_RT_ALERT:
804  tls_session->info.alert_level = buf[0];
805  tls_session->info.alert_description = buf[1];
806  tls_session->info.handshake_type = 0x00;
807  break;
808 
809  case SSL3_RT_HANDSHAKE:
810  tls_session->info.handshake_type = buf[0];
811  tls_session->info.alert_level = 0x00;
812  tls_session->info.alert_description = 0x00;
813  break;
814 
815 #ifdef SSL3_RT_HEARTBEAT
816  case TLS1_RT_HEARTBEAT:
817  uint8_t *p = buf;
818 
819  if ((len >= 3) && (p[0] == 1)) {
820  size_t payload_len;
821 
822  payload_len = fr_nbo_to_uint16(p + 1);
823  if ((payload_len + 3) > len) {
824  tls_session->invalid = true;
825  ROPTIONAL(REDEBUG, ERROR, "OpenSSL Heartbeat attack detected. Closing connection");
826  return;
827  }
828  }
829  break;
830 #endif
831  default:
832  break;
833  }
834 
835  session_msg_log(request, tls_session, (uint8_t const *)inbuf, len);
836 
837 #ifndef OPENSSL_NO_SSL_TRACE
839  SSL_trace(tls_session->info.origin,
840  tls_session->info.version,
841  tls_session->info.content_type,
842  inbuf, len,
843  ssl,
844  request ?
845  fr_tls_request_log_bio(request, L_DBG, L_DBG_LVL_3) :
846  fr_tls_global_log_bio(L_DBG, L_DBG_LVL_3));
847  }
848 #endif
849 }
850 
851 /*
852  * By setting the environment variable SSLKEYLOGFILE to a filename keying
853  * material will be exported that you may use with Wireshark to decode any
854  * TLS flows. Please see the following for more details:
855  *
856  * https://gitlab.com/wireshark/wireshark/-/wikis/TLS#tls-decryption
857  *
858  * An example logging session is (you should delete the file on each run):
859  *
860  * rm -f /tmp/sslkey.log; env SSLKEYLOGFILE=/tmp/sslkey.log freeradius -X | tee /tmp/debug
861  *
862  * Note that we rely on the OS to check file permissions. If the
863  * caller can run radiusd, then they can only write to files which
864  * they own. If radiusd is running as root, then only root can
865  * change the environment variables for radiusd.
866  */
867 void fr_tls_session_keylog_cb(const SSL *ssl, const char *line)
868 {
869  int fd;
870  size_t len;
871  const char *filename;
872  char buffer[64 + 2*SSL3_RANDOM_SIZE + 2*SSL_MAX_MASTER_KEY_LENGTH];
873 
874  /*
875  * Prefer the environment variable definition to the
876  * configuration file. This allows for "one-shot"
877  * dumping of EAP keys when you know you're not using
878  * RadSec, and you don't want to edit the configuration.
879  */
880  filename = getenv("SSLKEYLOGFILE");
881  if (!filename) {
882  fr_tls_conf_t *conf;
883 
884  conf = (fr_tls_conf_t *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF);
885  if (!conf || !conf->keylog_file || !*conf->keylog_file) return;
886 
887  filename = conf->keylog_file;
888  }
889 
890  /*
891  * We write all of the data at once. This is *generally*
892  * atomic on most systems.
893  */
894  len = strlen(line);
895  if ((len + 1) > sizeof(buffer)) {
896  DEBUG("SSLKEYLOGFILE buffer not large enough, max %lu, required %lu", sizeof(buffer), len + 1);
897  return;
898  }
899 
900  /*
901  * Add a \n, which means that in order to write() the
902  * buffer AND the trailing \n, we have to place both
903  * strings into the same buffer.
904  */
905  memcpy(buffer, line, len);
906  buffer[len] = '\n';
907 
908  fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
909  if (fd < 0) {
910  DEBUG("Failed to open file %s: %s", filename, strerror(errno));
911  return;
912  }
913 
914  /*
915  * This should work in most situations.
916  */
917  if (write(fd, buffer, len + 1) < 0) {
918  DEBUG("Failed to write to file %s: %s", filename, strerror(errno));
919  }
920 
921  close(fd);
922 }
923 
924 /** Decrypt application data
925  *
926  * @note Handshake must have completed before this function may be called.
927  *
928  * Feed data from dirty_in to OpenSSL, and read the clean data into clean_out.
929  *
930  * @param[in] request The current #request_t.
931  * @param[in] tls_session The current TLS session.
932  * @return
933  * - -1 on error.
934  * - 1 if more fragments are required to fully reassemble the record for decryption.
935  * - 0 if we decrypted a complete record.
936  */
937 int fr_tls_session_recv(request_t *request, fr_tls_session_t *tls_session)
938 {
939  int ret;
940 
941  fr_tls_session_request_bind(tls_session->ssl, request);
942 
943  if (!SSL_is_init_finished(tls_session->ssl)) {
944  REDEBUG("Attempted to read application data before handshake completed");
945  error:
946  ret = -1;
947  goto finish;
948  }
949 
950  /*
951  * Decrypt the complete record.
952  */
953  if (tls_session->dirty_in.used) {
954  ret = BIO_write(tls_session->into_ssl, tls_session->dirty_in.data, tls_session->dirty_in.used);
955  if (ret != (int) tls_session->dirty_in.used) {
956  record_init(&tls_session->dirty_in);
957  REDEBUG("Failed writing %zd bytes to SSL BIO: %d", tls_session->dirty_in.used, ret);
958  goto error;
959  }
960 
961  record_init(&tls_session->dirty_in);
962  }
963 
964  /*
965  * Clear the dirty buffer now that we are done with it
966  * and init the clean_out buffer to store decrypted data
967  */
968  record_init(&tls_session->clean_out);
969 
970  /*
971  * Read (and decrypt) the tunneled data from the
972  * SSL session, and put it into the decrypted
973  * data buffer.
974  */
975  ret = SSL_read(tls_session->ssl, tls_session->clean_out.data, sizeof(tls_session->clean_out.data));
976  if (ret < 0) {
977  int code;
978 
979  code = SSL_get_error(tls_session->ssl, ret);
980  switch (code) {
981  case SSL_ERROR_WANT_READ:
982  RWDEBUG("Peer indicated record was complete, but OpenSSL returned SSL_WANT_READ. "
983  "Attempting to continue");
984  ret = 1;
985  goto finish;
986 
987  case SSL_ERROR_WANT_WRITE:
988  REDEBUG("Error in fragmentation logic: SSL_WANT_WRITE");
989  goto error;
990 
991  case SSL_ERROR_NONE:
992  RDEBUG2("No application data received. Assuming handshake is continuing...");
993  ret = 0;
994  break;
995 
996  default:
997  REDEBUG("Error in fragmentation logic");
998  fr_tls_log_io_error(request, code, "SSL_read (%s)", __FUNCTION__);
999  goto error;
1000  }
1001  }
1002 
1003  /*
1004  * Passed all checks, successfully decrypted data
1005  */
1006  tls_session->clean_out.used = ret;
1007  ret = 0;
1008 
1009  if (RDEBUG_ENABLED3) {
1010  RHEXDUMP3(tls_session->clean_out.data, tls_session->clean_out.used,
1011  "Decrypted TLS application data (%zu bytes)", tls_session->clean_out.used);
1012  } else {
1013  RDEBUG2("Decrypted TLS application data (%zu bytes)", tls_session->clean_out.used);
1014  }
1015 finish:
1016  fr_tls_session_request_unbind(tls_session->ssl);
1017 
1018  return ret;
1019 }
1020 
1021 /** Encrypt application data
1022  *
1023  * @note Handshake must have completed before this function may be called.
1024  *
1025  * Take cleartext data from clean_in, and feed it to OpenSSL, reading
1026  * the encrypted data into dirty_out.
1027  *
1028  * @param[in] request The current request.
1029  * @param[in] tls_session The current TLS session.
1030  * @return
1031  * - -1 on failure.
1032  * - 0 on success.
1033  */
1034 int fr_tls_session_send(request_t *request, fr_tls_session_t *tls_session)
1035 {
1036  int ret = 0;
1037 
1038  fr_tls_session_request_bind(tls_session->ssl, request);
1039 
1040  if (!SSL_is_init_finished(tls_session->ssl)) {
1041  REDEBUG("Attempted to write application data before handshake completed");
1042  ret = -1;
1043  goto finish;
1044  }
1045 
1046  /*
1047  * If there's un-encrypted data in 'clean_in', then write
1048  * that data to the SSL session, and then call the BIO function
1049  * to get that encrypted data from the SSL session, into
1050  * a buffer which we can then package into an EAP packet.
1051  *
1052  * Based on Server's logic this clean_in is expected to
1053  * contain the data to send to the client.
1054  */
1055  if (tls_session->clean_in.used > 0) {
1056  if (RDEBUG_ENABLED3) {
1057  RHEXDUMP3(tls_session->clean_in.data, tls_session->clean_in.used,
1058  "TLS application data to encrypt (%zu bytes)", tls_session->clean_in.used);
1059  } else {
1060  RDEBUG2("TLS application data to encrypt (%zu bytes)", tls_session->clean_in.used);
1061  }
1062 
1063  ret = SSL_write(tls_session->ssl, tls_session->clean_in.data, tls_session->clean_in.used);
1064  record_to_buff(&tls_session->clean_in, NULL, ret);
1065 
1066  /* Get the dirty data from Bio to send it */
1067  ret = BIO_read(tls_session->from_ssl, tls_session->dirty_out.data,
1068  sizeof(tls_session->dirty_out.data));
1069  if (ret > 0) {
1070  tls_session->dirty_out.used = ret;
1071  ret = 0;
1072  } else {
1073  if (fr_tls_log_io_error(request, SSL_get_error(tls_session->ssl, ret),
1074  "SSL_write (%s)", __FUNCTION__) < 0) ret = -1;
1075  }
1076  }
1077 
1078 finish:
1079  fr_tls_session_request_unbind(tls_session->ssl);
1080 
1081  return ret;
1082 }
1083 
1084 /** Instruct fr_tls_session_async_handshake to create a synthesised TLS alert record and send it to the peer
1085  *
1086  */
1087 int fr_tls_session_alert(UNUSED request_t *request, fr_tls_session_t *session, uint8_t level, uint8_t description)
1088 {
1089  if (session->alerts_sent > 3) return -1; /* Some kind of state machine brokenness */
1090 
1091  /*
1092  * Ignore less severe alerts
1093  */
1094  if (session->pending_alert && (level < session->pending_alert_level)) return 0;
1095 
1096  session->pending_alert = true;
1097  session->pending_alert_level = level;
1098  session->pending_alert_description = description;
1099 
1100  return 0;
1101 }
1102 
1103 static void fr_tls_session_alert_send(request_t *request, fr_tls_session_t *session)
1104 {
1105  /*
1106  * Update our internal view of the session
1107  */
1108  session->info.origin = TLS_INFO_ORIGIN_RECORD_SENT;
1109  session->info.content_type = SSL3_RT_ALERT;
1110  session->info.alert_level = session->pending_alert_level;
1111  session->info.alert_description = session->pending_alert_description;
1112 
1113  session->dirty_out.data[0] = session->info.content_type;
1114  session->dirty_out.data[1] = 3;
1115  session->dirty_out.data[2] = 1;
1116  session->dirty_out.data[3] = 0;
1117  session->dirty_out.data[4] = 2;
1118  session->dirty_out.data[5] = session->pending_alert_level;
1119  session->dirty_out.data[6] = session->pending_alert_description;
1120 
1121  session->dirty_out.used = 7;
1122 
1123  session->pending_alert = false;
1124  session->alerts_sent++;
1125 
1126  SSL_clear(session->ssl); /* Reset the SSL *, to allow the client to restart the session */
1127 
1128  session_msg_log(request, session, session->dirty_out.data, session->dirty_out.used);
1129 }
1130 
1131 /** Finish off a handshake round, possibly adding attributes to the request
1132  *
1133  */
1134 static unlang_action_t tls_session_async_handshake_done_round(UNUSED rlm_rcode_t *p_result, UNUSED int *priority,
1135  request_t *request, void *uctx)
1136 {
1137  fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1138  int ret;
1139 
1140  RDEBUG3("entered state %s", __FUNCTION__);
1141 
1142  /*
1143  * This only occurs once per session, where calling
1144  * SSL_read updates the state of the SSL session, setting
1145  * this flag to true.
1146  *
1147  * Callbacks provide enough info so we don't need to
1148  * print debug statements when the handshake is in other
1149  * states.
1150  */
1151  if (SSL_is_init_finished(tls_session->ssl)) {
1152  SSL_CIPHER const *cipher;
1153  fr_pair_t *vp;
1154  char const *version;
1155 
1156  char cipher_desc[256], cipher_desc_clean[256];
1157  char *p = cipher_desc, *q = cipher_desc_clean;
1158 
1159  cipher = SSL_get_current_cipher(tls_session->ssl);
1160  SSL_CIPHER_description(cipher, cipher_desc, sizeof(cipher_desc));
1161 
1162  /*
1163  * Cleanup the output from OpenSSL
1164  * Seems to print info in a tabular format.
1165  */
1166  while (*p != '\0') {
1167  if (isspace((uint8_t) *p)) {
1168  *q++ = *p;
1169  fr_skip_whitespace(p);
1170  continue;
1171  }
1172  *q++ = *p++;
1173  }
1174  *q = '\0';
1175 
1176  RDEBUG2("Cipher suite: %s", cipher_desc_clean);
1177 
1178  RDEBUG2("Adding TLS session information to request");
1179  vp = fr_pair_afrom_da(request->session_state_ctx, attr_tls_session_cipher_suite);
1180  if (vp) {
1181  fr_pair_value_strdup(vp, SSL_CIPHER_get_name(cipher), false);
1182  fr_pair_append(&request->session_state_pairs, vp);
1183  RINDENT();
1184  RDEBUG2("&session-state.%pP", vp);
1185  REXDENT();
1186  }
1187 
1188  if (((size_t)tls_session->info.version >= NUM_ELEMENTS(tls_version_str)) ||
1189  !tls_version_str[tls_session->info.version]) {
1190  version = "UNKNOWN";
1191  } else {
1192  version = tls_version_str[tls_session->info.version];
1193  }
1194 
1195  vp = fr_pair_afrom_da(request->session_state_ctx, attr_tls_session_version);
1196  if (vp) {
1197  fr_pair_value_strdup(vp, version, false);
1198  fr_pair_append(&request->session_state_pairs, vp);
1199  RINDENT();
1200  RDEBUG2("&session-state.TLS-Session-Version := \"%s\"", version);
1201  REXDENT();
1202  }
1203 
1204  /*
1205  * Cache the SSL_SESSION pointer.
1206  *
1207  * Which contains all the data we need for session resumption.
1208  */
1209  if (!tls_session->session) {
1210  tls_session->session = SSL_get_session(tls_session->ssl);
1211  if (!tls_session->session) {
1212  REDEBUG("Failed getting TLS session");
1213  error:
1214  tls_session->result = FR_TLS_RESULT_ERROR;
1215  fr_tls_session_request_unbind(tls_session->ssl);
1217  }
1218  }
1219 
1220  if (RDEBUG_ENABLED3) {
1221  if (SSL_SESSION_print(fr_tls_request_log_bio(request, L_DBG, L_DBG_LVL_3),
1222  tls_session->session) != 1) {
1223  } else {
1224  RDEBUG3("Failed retrieving session data");
1225  }
1226  }
1227 
1228  /*
1229  * Session was resumed, add attribute to mark it as such.
1230  */
1231  if (SSL_session_reused(tls_session->ssl)) {
1232  /*
1233  * Mark the request as resumed.
1234  */
1236  vp->vp_bool = true;
1237  }
1238  }
1239 
1240  /*
1241  * Get data to pack and send back to the TLS peer.
1242  */
1243  ret = BIO_ctrl_pending(tls_session->from_ssl);
1244  if (ret > 0) {
1245  ret = BIO_read(tls_session->from_ssl, tls_session->dirty_out.data,
1246  sizeof(tls_session->dirty_out.data));
1247  if (ret > 0) {
1248  tls_session->dirty_out.used = ret;
1249  } else if (BIO_should_retry(tls_session->from_ssl)) {
1250  record_init(&tls_session->dirty_in);
1251  RDEBUG2("Asking for more data in tunnel");
1252 
1253  } else {
1254  fr_tls_log(NULL, NULL);
1255  record_init(&tls_session->dirty_in);
1256  goto error;
1257  }
1258  } else {
1259  /* Its clean application data, do whatever we want */
1260  record_init(&tls_session->clean_out);
1261  }
1262 
1263  /*
1264  * Trash the current data in dirty_out, and synthesize
1265  * a TLS error record.
1266  *
1267  * OpensSL annoyingly provides no mechanism for us to
1268  * send alerts, and we need to send alerts as part of
1269  * RFC 5216, so this is our only option.
1270  */
1271  if (tls_session->pending_alert) fr_tls_session_alert_send(request, tls_session);
1272 
1273  /* We are done with dirty_in, reinitialize it */
1274  record_init(&tls_session->dirty_in);
1275 
1276  tls_session->result = FR_TLS_RESULT_SUCCESS;
1277  fr_tls_session_request_unbind(tls_session->ssl);
1279 }
1280 
1281 /** Try very hard to get the SSL * into a consistent state where it's not yielded
1282  *
1283  * ...because if it's yielded, we'll probably leak thread contexts and all kinds of memory.
1284  *
1285  * @param[in] request being cancelled.
1286  * @param[in] action we're being signalled with.
1287  * @param[in] uctx the SSL * to cancel.
1288  */
1289 static void tls_session_async_handshake_signal(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
1290 {
1291  fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1292  int ret;
1293 
1294  /*
1295  * We might want to set can_pause = false here
1296  * but that would trigger asserts in the
1297  * cache code.
1298  */
1299 
1300  /*
1301  * If SSL_get_error returns SSL_ERROR_WANT_ASYNC
1302  * it means we're yielded in the middle of a
1303  * callback.
1304  *
1305  * Keep calling SSL_read() in a loop until we
1306  * no longer get SSL_ERROR_WANT_ASYNC, then
1307  * shut it down so it's in a consistent state.
1308  *
1309  * It'll get freed later when the request is
1310  * freed.
1311  */
1312  for (ret = tls_session->last_ret;
1313  SSL_get_error(tls_session->ssl, ret) == SSL_ERROR_WANT_ASYNC;
1314  ret = SSL_read(tls_session->ssl, tls_session->clean_out.data + tls_session->clean_out.used,
1315  sizeof(tls_session->clean_out.data) - tls_session->clean_out.used));
1316 
1317  /*
1318  * Unbind the cancelled request from the SSL *
1319  */
1320  fr_tls_session_request_unbind(tls_session->ssl);
1321 }
1322 
1323 /** Call SSL_read() to continue the TLS state machine
1324  *
1325  * This function may be called multiple times, once after every asynchronous request.
1326  *
1327  * @param[in,out] p_result UNUSED.
1328  * @param[out] priority UNUSED
1329  * @param[in] request The current request.
1330  * @param[in] uctx #fr_tls_session_t to continue.
1331  * @return
1332  * - UNLANG_ACTION_CALCULATE_RESULT - We're done with this round.
1333  * - UNLANG_ACTION_PUSHED_CHILD - Need to perform more asynchronous actions.
1334  */
1335 static unlang_action_t tls_session_async_handshake_cont(rlm_rcode_t *p_result, int *priority,
1336  request_t *request, void *uctx)
1337 {
1338  fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1339  int err;
1340 
1341  RDEBUG3("(re-)entered state %s", __FUNCTION__);
1342 
1343  /*
1344  * Magic/More magic? Although SSL_read is normally
1345  * used to read application data, it will also
1346  * continue the TLS handshake. Removing this call will
1347  * cause the handshake to fail.
1348  *
1349  * We don't ever expect to actually *receive* application
1350  * data here.
1351  *
1352  * The reason why we call SSL_read instead of SSL_accept,
1353  * or SSL_connect, as it allows this function
1354  * to be used, irrespective or whether we're acting
1355  * as a client or a server.
1356  *
1357  * If acting as a client SSL_set_connect_state must have
1358  * been called before this function.
1359  *
1360  * If acting as a server SSL_set_accept_state must have
1361  * been called before this function.
1362  */
1363  tls_session->can_pause = true;
1364  tls_session->last_ret = SSL_read(tls_session->ssl, tls_session->clean_out.data + tls_session->clean_out.used,
1365  sizeof(tls_session->clean_out.data) - tls_session->clean_out.used);
1366  tls_session->can_pause = false;
1367  if (tls_session->last_ret > 0) {
1368  tls_session->clean_out.used += tls_session->last_ret;
1369 
1370  /*
1371  * Round successful, and we don't need to do any
1372  * further processing.
1373  */
1374  tls_session->result = FR_TLS_RESULT_SUCCESS;
1375  finish:
1376  /*
1377  * Was bound by caller
1378  */
1379  fr_tls_session_request_unbind(tls_session->ssl);
1381  }
1382 
1383  /*
1384  * Bug in OpenSSL 3.0 - Normal handshaking behaviour
1385  * results in spurious "BIO_R_UNSUPPORTED_METHOD"
1386  * errors.
1387  *
1388  * SSL_get_error apparently returns SSL_ERROR_SSL if
1389  * there are any errors in the stack. This masks
1390  * SSL_ERROR_WANT_ASYNC and causes the handshake to
1391  * fail.
1392  *
1393  * Note: We may want some version of this code
1394  * included for all OpenSSL versions.
1395  *
1396  * It would call ERR_GET_FATAL() on each of the errors
1397  * in the stack to drain non-fatal errors and prevent
1398  * the other (more useful) return codes of
1399  * SSL_get_error from being masked. I guess we'll see
1400  * if this occurs in other scenarios.
1401  */
1402  if (SSL_get_error(tls_session->ssl, tls_session->last_ret) == SSL_ERROR_SSL) {
1403  unsigned long ssl_err;
1404 
1405  /*
1406  * Some weird OpenSSL thing marking ERR_GET_REASON
1407  * as "unused". Unclear why this is done as it's
1408  * not deprecated.
1409  */
1411 DIAG_OFF(used-but-marked-unused)
1412  while ((ssl_err = ERR_peek_error()) && (ERR_GET_REASON(ssl_err) == BIO_R_UNSUPPORTED_METHOD)) {
1413  (void) ERR_get_error();
1414  }
1415 DIAG_ON(used-but-marked-unused)
1417  }
1418 
1419  /*
1420  * Deal with asynchronous requests from OpenSSL.
1421  * These aren't actually errors, they're the
1422  * result of one of our callbacks indicating that
1423  * it'd like to perform the operation
1424  * asynchronously.
1425  */
1426  switch (err = SSL_get_error(tls_session->ssl, tls_session->last_ret)) {
1427  case SSL_ERROR_WANT_ASYNC: /* Certification validation or cache loads */
1428  {
1429  unlang_action_t ua;
1430 
1431  RDEBUG3("Performing async action for libssl");
1432 
1433  /*
1434  * Call this function again once we're done
1435  * asynchronously satisfying the load request.
1436  */
1437  if (unlikely(unlang_function_repeat_set(request, tls_session_async_handshake_cont) < 0)) {
1438  error:
1439  tls_session->result = FR_TLS_RESULT_ERROR;
1440  goto finish;
1441  }
1442 
1443  /*
1444  * First service any pending cache actions
1445  */
1446  ua = fr_tls_cache_pending_push(request, tls_session);
1447  switch (ua) {
1448  case UNLANG_ACTION_FAIL:
1449  IGNORE(unlang_function_clear(request), int);
1450  goto error;
1451 
1453  return ua;
1454 
1455  default:
1456  break;
1457  }
1458 
1459  /*
1460  * Next service any pending certificate
1461  * validation actions.
1462  */
1463  ua = fr_tls_verify_cert_pending_push(request, tls_session);
1464  switch (ua) {
1465  case UNLANG_ACTION_FAIL:
1466  IGNORE(unlang_function_clear(request), int);
1467  goto error;
1468 
1469  default:
1470  return ua;
1471  }
1472  }
1473 
1474  case SSL_ERROR_WANT_ASYNC_JOB:
1475  RERROR("No async jobs available in pool, increase thread.openssl_async_pool_max");
1476  goto error;
1477 
1478  default:
1479  /*
1480  * Returns 0 if we can continue processing the handshake
1481  * Returns -1 if we encountered a fatal error.
1482  */
1483  if (fr_tls_log_io_error(request,
1484  err, "SSL_read (%s)", __FUNCTION__) < 0) goto error;
1485  return tls_session_async_handshake_done_round(p_result, priority, request, uctx);
1486  }
1487 }
1488 
1489 /** Ingest data for another handshake round
1490  *
1491  * Advance the TLS handshake by feeding OpenSSL data from dirty_in,
1492  * and reading data from OpenSSL into dirty_out.
1493  *
1494  * Calls #tls_session_async_handshake_read to perform the actual ingestion.
1495  * #tls_session_async_handshake_read is split out because we may need to call
1496  * it multiple times, once after every async action.
1497  *
1498  * @param[in,out] p_result UNUSED.
1499  * @param[out] priority UNUSED
1500  * @param[in] request The current request.
1501  * @param[in] uctx #fr_tls_session_t to continue.
1502  * @return
1503  * - UNLANG_ACTION_CALCULATE_RESULT - We're done with this round.
1504  * - UNLANG_ACTION_PUSHED_CHILD - Need to perform more asynchronous actions.
1505  */
1506 static unlang_action_t tls_session_async_handshake(rlm_rcode_t *p_result, int *priority,
1507  request_t *request, void *uctx)
1508 {
1509  fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1510  int ret;
1511 
1512  RDEBUG3("entered state %s", __FUNCTION__);
1513 
1514  tls_session->result = FR_TLS_RESULT_IN_PROGRESS;
1515 
1516  fr_tls_session_request_bind(tls_session->ssl, request); /* May be unbound in this function or asynchronously */
1517 
1518  /*
1519  * This is a logic error. fr_tls_session_async_handshake
1520  * must not be called if the handshake is
1521  * complete fr_tls_session_recv must be
1522  * called instead.
1523  */
1524  if (SSL_is_init_finished(tls_session->ssl)) {
1525  REDEBUG("Attempted to continue TLS handshake, but handshake has completed");
1526  error:
1527  tls_session->result = FR_TLS_RESULT_ERROR;
1528  fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1530  }
1531 
1532  if (tls_session->invalid) {
1533  REDEBUG("Preventing invalid session from continuing");
1534  goto error;
1535  }
1536 
1537  /*
1538  * Feed dirty data into OpenSSL, so that is can either
1539  * process it as Application data (decrypting it)
1540  * or continue the TLS handshake.
1541  */
1542  if (tls_session->dirty_in.used) {
1543  ret = BIO_write(tls_session->into_ssl, tls_session->dirty_in.data, tls_session->dirty_in.used);
1544  if (ret != (int)tls_session->dirty_in.used) {
1545  REDEBUG("Failed writing %zd bytes to TLS BIO: %d", tls_session->dirty_in.used, ret);
1546  record_init(&tls_session->dirty_in);
1547  goto error;
1548  }
1549  record_init(&tls_session->dirty_in);
1550  }
1551 
1552  return tls_session_async_handshake_cont(p_result, priority, request, uctx); /* Must unbind request, possibly asynchronously */
1553 }
1554 
1555 /** Push a handshake call onto the stack
1556  *
1557  * We push the handshake frame (as opposed to having the caller do it),
1558  * so that we guarantee there's a frame that the handshake function can
1559  * manipulate to manage its own state.
1560  *
1561  * The result of processing this handshake round can be found in
1562  * tls_session->result.
1563  *
1564  * @param[in] request The current request.
1565  * @param[in] tls_session to continue handshaking.
1566  * @return
1567  * - UNLANG_ACTION_PUSHED_CHILD on success.
1568  * - UNLANG_ACTION_FAIL on failure.
1569  */
1570 unlang_action_t fr_tls_session_async_handshake_push(request_t *request, fr_tls_session_t *tls_session)
1571 {
1572  return unlang_function_push(request,
1573  tls_session_async_handshake,
1574  NULL,
1575  tls_session_async_handshake_signal,
1576  ~FR_SIGNAL_CANCEL,
1578  tls_session);
1579 }
1580 
1581 /** Free a TLS session and any associated OpenSSL data
1582  *
1583  * @param session to free.
1584  * @return 0.
1585  */
1586 static int _fr_tls_session_free(fr_tls_session_t *session)
1587 {
1588  if (session->ssl) {
1589  SSL_set_quiet_shutdown(session->ssl, 1);
1590  SSL_shutdown(session->ssl);
1591  SSL_free(session->ssl);
1592  session->ssl = NULL;
1593  }
1594 
1595  return 0;
1596 }
1597 
1598 static void session_init(fr_tls_session_t *session)
1599 {
1600  session->ssl = NULL;
1601  session->into_ssl = session->from_ssl = NULL;
1602  record_init(&session->clean_in);
1603  record_init(&session->clean_out);
1604  record_init(&session->dirty_in);
1605  record_init(&session->dirty_out);
1606 
1607  memset(&session->info, 0, sizeof(session->info));
1608 
1609  session->mtu = 0;
1610  session->opaque = NULL;
1611 }
1612 
1613 /** Create a new client TLS session
1614  *
1615  * Configures a new client TLS session, configuring options, setting callbacks etc...
1616  *
1617  * @param[in] ctx to alloc session data in. Should usually be NULL unless the lifetime of the
1618  * session is tied to another talloc'd object.
1619  * @param[in] ssl_ctx containing the base configuration for this session.
1620  * @return
1621  * - A new session on success.
1622  * - NULL on error.
1623  */
1624 fr_tls_session_t *fr_tls_session_alloc_client(TALLOC_CTX *ctx, SSL_CTX *ssl_ctx)
1625 {
1626  int verify_mode;
1627  fr_tls_session_t *tls_session = NULL;
1628  fr_tls_conf_t *conf = fr_tls_ctx_conf(ssl_ctx);
1629 
1630  MEM(tls_session = talloc_zero(ctx, fr_tls_session_t));
1631  talloc_set_destructor(tls_session, _fr_tls_session_free);
1632  fr_pair_list_init(&tls_session->extra_pairs);
1633 
1634  tls_session->ssl = SSL_new(ssl_ctx);
1635  if (!tls_session->ssl) {
1636  talloc_free(tls_session);
1637  return NULL;
1638  }
1639 
1640  /*
1641  * Add the message callback to identify what type of
1642  * message/handshake is passed
1643  */
1644  SSL_set_msg_callback(tls_session->ssl, fr_tls_session_msg_cb);
1645  SSL_set_msg_callback_arg(tls_session->ssl, tls_session);
1646  SSL_set_info_callback(tls_session->ssl, fr_tls_session_info_cb);
1647 
1648  /*
1649  * Always verify the peer certificate.
1650  */
1651  DEBUG2("Requiring Server certificate");
1652  verify_mode = SSL_VERIFY_PEER;
1653  verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1654 
1655  /*
1656  * Callback should be fr_tls_verify_cert_cb but this
1657  * requires support around SSL_connect for dealing
1658  * with async.
1659  *
1660  * If the callback is NULL OpenSSL uses its own validation
1661  * function, and the flags modifies that function's
1662  * behaviour.
1663  */
1664  SSL_set_verify(tls_session->ssl, verify_mode, NULL);
1665  SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
1666  SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)tls_session);
1667 
1668  tls_session->mtu = conf->fragment_size;
1669 
1670  return tls_session;
1671 }
1672 
1673 /** Create a new server TLS session
1674  *
1675  * Configures a new server TLS session, configuring options, setting callbacks etc...
1676  *
1677  * @param[in] ctx to alloc session data in. Should usually be NULL
1678  * unless the lifetime of the session is tied to another
1679  * talloc'd object.
1680  * @param[in] ssl_ctx containing the base configuration for this session.
1681  * @param[in] request The current #request_t.
1682  * @param[in] dynamic_mtu If greater than 100, overrides the MTU configured for the SSL_CTX.
1683  * @param[in] client_cert Whether to require a client_cert.
1684  * @return
1685  * - A new session on success.
1686  * - NULL on error.
1687  */
1688 fr_tls_session_t *fr_tls_session_alloc_server(TALLOC_CTX *ctx, SSL_CTX *ssl_ctx, request_t *request, size_t dynamic_mtu, bool client_cert)
1689 {
1690  fr_tls_session_t *tls_session = NULL;
1691  SSL *ssl = NULL;
1692  int verify_mode = 0;
1693  fr_pair_t *vp;
1694  fr_tls_conf_t *conf = fr_tls_ctx_conf(ssl_ctx);
1695 
1696  RDEBUG2("Initiating new TLS session");
1697 
1698  MEM(tls_session = talloc_zero(ctx, fr_tls_session_t));
1699 
1700  ssl = SSL_new(ssl_ctx);
1701  if (ssl == NULL) {
1702  fr_tls_log(request, "Error creating new TLS session");
1703  return NULL;
1704  }
1705  fr_pair_list_init(&tls_session->extra_pairs);
1706 
1707  session_init(tls_session);
1708  tls_session->ctx = ssl_ctx;
1709  tls_session->ssl = ssl;
1710  talloc_set_destructor(tls_session, _fr_tls_session_free);
1711 
1712  fr_tls_session_request_bind(tls_session->ssl, request); /* Is unbound in this function */
1713 
1714  /*
1715  * Initialize callbacks
1716  */
1717  tls_session->record_init = record_init;
1718  tls_session->record_close = record_close;
1719  tls_session->record_from_buff = record_from_buff;
1720  tls_session->record_to_buff = record_to_buff;
1721 
1722  /*
1723  * Create & hook the BIOs to handle the dirty side of the
1724  * SSL. This is *very important* as we want to handle
1725  * the transmission part. Now the only IO interface
1726  * that SSL is aware of, is our defined BIO buffers.
1727  *
1728  * This means that all SSL IO is done to/from memory,
1729  * and we can update those BIOs from the packets we've
1730  * received.
1731  */
1732  MEM(tls_session->into_ssl = BIO_new(BIO_s_mem()));
1733  MEM(tls_session->from_ssl = BIO_new(BIO_s_mem()));
1734  SSL_set_bio(tls_session->ssl, tls_session->into_ssl, tls_session->from_ssl);
1735 
1736  /*
1737  * Add the message callback to identify what type of
1738  * message/handshake is passed
1739  */
1740  SSL_set_msg_callback(ssl, fr_tls_session_msg_cb);
1741  SSL_set_msg_callback_arg(ssl, tls_session);
1742  SSL_set_info_callback(ssl, fr_tls_session_info_cb);
1743 
1744  /*
1745  * This sets the context sessions can be resumed in.
1746  * This is to prevent sessions being created by one application
1747  * and used by another. In our case it prevents sessions being
1748  * reused between modules, or TLS server components such as
1749  * RADSEC.
1750  *
1751  * A context must always be set when doing session resumption
1752  * otherwise session resumption will fail.
1753  *
1754  * As the context ID must be <= 32, we digest the context
1755  * data with sha256.
1756  *
1757  * This seems to only be used for stateful session resumption
1758  * not session-tickets
1759  */
1760  if (conf->cache.mode != FR_TLS_CACHE_DISABLED) {
1761  char *context_id;
1762  EVP_MD_CTX *md_ctx;
1763  uint8_t digest[SHA256_DIGEST_LENGTH];
1764 
1765  static_assert(sizeof(digest) <= SSL_MAX_SSL_SESSION_ID_LENGTH,
1766  "SSL_MAX_SSL_SESSION_ID_LENGTH must be >= SHA256_DIGEST_LENGTH");
1767  fr_assert(conf->cache.id_name);
1768 
1769  if (tmpl_aexpand(tls_session, &context_id, request, conf->cache.id_name, NULL, NULL) < 0) {
1770  RPEDEBUG("Failed expanding session ID");
1771  error:
1772  fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1773  talloc_free(tls_session);
1774  return NULL;
1775  }
1776 
1777  MEM(md_ctx = EVP_MD_CTX_create());
1778  EVP_DigestInit_ex(md_ctx, EVP_sha256(), NULL);
1779  EVP_DigestUpdate(md_ctx, context_id, talloc_array_length(context_id) - 1);
1780  EVP_DigestFinal_ex(md_ctx, digest, NULL);
1781  EVP_MD_CTX_destroy(md_ctx);
1782  talloc_free(context_id);
1783 
1784  if (!fr_cond_assert(SSL_set_session_id_context(tls_session->ssl,
1785  digest, sizeof(digest)) == 1)) goto error;
1786  }
1787 
1788  /*
1789  * Add the session certificate to the session.
1790  */
1791  vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_tls_session_cert_file);
1792  if (vp) {
1793  RDEBUG2("Loading TLS session certificate \"%pV\"", &vp->data);
1794 
1795  if (SSL_use_certificate_file(tls_session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
1796  fr_tls_log(request, "Failed loading TLS session certificate \"%s\"",
1797  vp->vp_strvalue);
1798  goto error;
1799  }
1800 
1801  if (SSL_use_PrivateKey_file(tls_session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
1802  fr_tls_log(request, "Failed loading TLS session certificate \"%s\"",
1803  vp->vp_strvalue);
1804  goto error;
1805  }
1806 
1807  if (SSL_check_private_key(tls_session->ssl) != 1) {
1808  fr_tls_log(request, "Failed validating TLS session certificate \"%s\"",
1809  vp->vp_strvalue);
1810  goto error;
1811  }
1812  /*
1813  * Better to perform explicit checks, than rely
1814  * on OpenSSL's opaque error messages.
1815  */
1816  } else {
1817  if (!conf->chains || !conf->chains[0]->private_key_file) {
1818  ERROR("TLS Server requires a private key file");
1819  goto error;
1820  }
1821 
1822  if (!conf->chains || !conf->chains[0]->certificate_file) {
1823  ERROR("TLS Server requires a certificate file");
1824  goto error;
1825  }
1826  }
1827 
1828  /** Dynamic toggle for allowing disallowing client certs
1829  *
1830  * This is mainly used for testing in environments where we can't
1831  * get test credentials for the host.
1832  */
1833  vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_tls_session_require_client_cert);
1834  if (vp) client_cert = vp->vp_bool;
1835 
1836  /*
1837  * In Server mode we only accept.
1838  *
1839  * This sets up the SSL session to work correctly with
1840  * fr_tls_session_handhsake.
1841  */
1842  SSL_set_accept_state(tls_session->ssl);
1843 
1844  /*
1845  * Verify the peer certificate, if asked.
1846  */
1847  if (client_cert) {
1848  RDEBUG2("Setting verify mode to require certificate from client");
1849  verify_mode = SSL_VERIFY_PEER;
1850  verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1851  verify_mode |= SSL_VERIFY_CLIENT_ONCE;
1852  }
1853  tls_session->verify_client_cert = client_cert;
1854 
1855  SSL_set_verify(tls_session->ssl, verify_mode, fr_tls_verify_cert_cb);
1856  SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
1857  SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)tls_session);
1858 
1859  tls_session->mtu = conf->fragment_size;
1860  if (dynamic_mtu > 100 && dynamic_mtu < tls_session->mtu) {
1861  RDEBUG2("Setting fragment_len to %zu from dynamic_mtu", dynamic_mtu);
1862  tls_session->mtu = dynamic_mtu;
1863  }
1864 
1865  if (conf->cache.mode != FR_TLS_CACHE_DISABLED) {
1866  tls_session->allow_session_resumption = true; /* otherwise it's false */
1867  fr_tls_cache_session_alloc(tls_session);
1868  }
1869 
1870  fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1871 
1872  return tls_session;
1873 }
1874 #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:39
@ 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:37
static int const char char buffer[256]
Definition: acutest.h:574
int const char int line
Definition: acutest.h:702
#define fr_base16_decode(_err, _out, _in, _no_trailing)
Definition: base16.h:95
#define IGNORE(_expr, _type)
Definition: build.h:505
#define DIAG_UNKNOWN_PRAGMAS
Definition: build.h:454
#define DIAG_ON(_x)
Definition: build.h:456
#define static_assert
For systems with an old version libc, define static_assert.
Definition: build.h:35
#define unlikely(_x)
Definition: build.h:379
#define UNUSED
Definition: build.h:313
#define NUM_ELEMENTS(_t)
Definition: build.h:335
#define DIAG_OFF(_x)
Definition: build.h:455
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition: dbuff.h:514
fr_dcursor_eval_t void const * uctx
Definition: dcursor.h:546
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:139
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
#define DEBUG(fmt,...)
Definition: dhcpclient.c:39
static fr_slen_t err
Definition: dict.h:821
static fr_slen_t in
Definition: dict.h:821
int unlang_function_clear(request_t *request)
Clear pending repeat function calls, and remove the signal handler.
Definition: function.c:160
#define unlang_function_repeat_set(_request, _repeat)
Set a new repeat function for an existing function frame.
Definition: function.h:89
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
Definition: function.h:111
#define UNLANG_SUB_FRAME
Definition: interpret.h:36
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition: log.h:443
#define DEBUG_ENABLED2
True if global debug level 1-2 messages are enabled.
Definition: log.h:258
#define DEBUG3(_fmt,...)
Definition: log.h:266
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
Definition: log.h:528
#define RWDEBUG(fmt,...)
Definition: log.h:361
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition: log.h:335
#define RDEBUG3(fmt,...)
Definition: log.h:343
#define DEBUG_ENABLED4
True if global debug level 1-3 messages are enabled.
Definition: log.h:260
#define RHEXDUMP4(_data, _len, _fmt,...)
Definition: log.h:706
#define RERROR(fmt,...)
Definition: log.h:298
#define DEBUG4(_fmt,...)
Definition: log.h:267
#define ROPTIONAL_ENABLED(_e_request, _e_global)
Check if a debug level is set by the request (if !NULL) or by the global log.
Definition: log.h:542
#define RPEDEBUG(fmt,...)
Definition: log.h:376
#define RHEXDUMP3(_data, _len, _fmt,...)
Definition: log.h:705
#define RDEBUG4(fmt,...)
Definition: log.h:344
#define DEBUG_ENABLED3
True if global debug level 1-3 messages are enabled.
Definition: log.h:259
#define RDEBUG_ENABLED4
True if request debug level 1-4 messages are enabled.
Definition: log.h:336
#define HEXDUMP4(_data, _len, _fmt,...)
Definition: log.h:724
#define RPWDEBUG2(fmt,...)
Definition: log.h:367
#define REDEBUG4(fmt,...)
Definition: log.h:374
#define RINDENT()
Indent R* messages by one level.
Definition: log.h:430
HIDDEN fr_dict_attr_t const * attr_session_resumed
HIDDEN fr_dict_attr_t const * attr_tls_session_version
HIDDEN fr_dict_attr_t const * attr_tls_session_require_client_cert
HIDDEN fr_dict_attr_t const * attr_tls_client_error_code
HIDDEN fr_dict_attr_t const * attr_tls_session_cipher_suite
HIDDEN fr_dict_attr_t const * attr_tls_psk_identity
HIDDEN fr_dict_attr_t const * attr_tls_session_cert_file
talloc_free(reap)
@ L_DBG_LVL_3
3rd highest priority debug messages (-xxx | -Xx).
Definition: log.h:72
@ L_DBG
Only displayed when debugging is enabled.
Definition: log.h:59
ssize_t xlat_eval(char *out, size_t outlen, request_t *request, char const *fmt, xlat_escape_legacy_t escape, void const *escape_ctx)
Definition: merged_model.c:215
unsigned char uint8_t
Definition: merged_model.c:30
#define UINT8_MAX
Definition: merged_model.c:32
static size_t used
#define fr_skip_whitespace(_p)
Skip whitespace ('\t', '\n', '\v', '\f', '\r', ' ')
Definition: misc.h:59
static uint16_t fr_nbo_to_uint16(uint8_t const data[static sizeof(uint16_t)])
Read an unsigned 16bit integer from wire format (big endian)
Definition: nbo.h:144
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition: pair.c:693
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition: pair.c:283
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition: pair.c:2634
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition: pair.c:1345
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition: pair.c:46
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, bool tainted)
Convert string value to native attribute value.
Definition: pair.c:2589
#define pair_update_request(_attr, _da)
Definition: radclient-ng.c:60
#define REDEBUG(fmt,...)
Definition: radclient.h:52
#define RDEBUG_ENABLED2()
Definition: radclient.h:50
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
#define DEBUG2(fmt,...)
Definition: radclient.h:43
static rs_t * conf
Definition: radsniff.c:53
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
#define FR_SBUFF_IN(_start, _len_or_end)
#define tmpl_aexpand(_ctx, _out, _request, _vpt, _escape, _escape_ctx)
Expand a tmpl to a C type, allocing a new buffer to hold the string.
Definition: tmpl.h:1070
fr_signal_t
Definition: signal.h:48
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:689
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_pair_t * vp
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:34
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
close(uq->fd)
static fr_slen_t data
Definition: value.h:1265
static size_t char fr_sbuff_t size_t inlen
Definition: value.h:997
static size_t char ** out
Definition: value.h:997