The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
conf.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: 8e13f73c06becd6247ac40679c3359e67570156d $
19  *
20  * @file tls/conf.c
21  * @brief Configuration parsing for TLS servers and clients.
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 RCSID("$Id: 8e13f73c06becd6247ac40679c3359e67570156d $")
28 USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
29 
30 #ifdef WITH_TLS
31 #define LOG_PREFIX "tls"
32 
33 #ifdef HAVE_SYS_STAT_H
34 # include <sys/stat.h>
35 #endif
36 #include <openssl/conf.h>
37 
38 #include <freeradius-devel/server/module.h>
39 #include <freeradius-devel/server/virtual_servers.h>
40 #include <freeradius-devel/util/debug.h>
41 #include <freeradius-devel/util/syserror.h>
42 #include <freeradius-devel/util/rand.h>
43 
44 #include "base.h"
45 #include "log.h"
46 
47 static int tls_conf_parse_cache_mode(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule);
48 
49 /** Certificate formats
50  *
51  */
52 static fr_table_num_sorted_t const certificate_format_table[] = {
53  { L("ASN1"), SSL_FILETYPE_ASN1 },
54  { L("DER"), SSL_FILETYPE_ASN1 }, /* Alternate name for ASN1 */
55  { L("PEM"), SSL_FILETYPE_PEM }
56 };
57 static size_t certificate_format_table_len = NUM_ELEMENTS(certificate_format_table);
58 
59 static fr_table_num_sorted_t const chain_verify_mode_table[] = {
60  { L("hard"), FR_TLS_CHAIN_VERIFY_HARD },
61  { L("none"), FR_TLS_CHAIN_VERIFY_NONE },
62  { L("soft"), FR_TLS_CHAIN_VERIFY_SOFT }
63 };
64 static size_t chain_verify_mode_table_len = NUM_ELEMENTS(chain_verify_mode_table);
65 
66 static fr_table_num_sorted_t const cache_mode_table[] = {
67  { L("auto"), FR_TLS_CACHE_AUTO },
68  { L("disabled"), FR_TLS_CACHE_DISABLED },
69  { L("stateful"), FR_TLS_CACHE_STATEFUL },
70  { L("stateless"), FR_TLS_CACHE_STATELESS }
71 };
72 static size_t cache_mode_table_len = NUM_ELEMENTS(cache_mode_table);
73 
74 static fr_table_num_sorted_t const verify_mode_table[] = {
75  { L("all"), FR_TLS_VERIFY_MODE_ALL },
76  { L("client"), FR_TLS_VERIFY_MODE_LEAF },
77  { L("client-and-issuer"), FR_TLS_VERIFY_MODE_LEAF | FR_TLS_VERIFY_MODE_ISSUER },
78  { L("disabled"), FR_TLS_VERIFY_MODE_DISABLED },
79  { L("untrusted"), FR_TLS_VERIFY_MODE_UNTRUSTED }
80 };
81 static size_t verify_mode_table_len = NUM_ELEMENTS(verify_mode_table);
82 
83 static conf_parser_t tls_cache_config[] = {
84  { FR_CONF_OFFSET("mode", fr_tls_cache_conf_t, mode),
85  .func = tls_conf_parse_cache_mode,
86  .uctx = &(cf_table_parse_ctx_t){
87  .table = cache_mode_table,
88  .len = &cache_mode_table_len
89  },
90  .dflt = "auto" },
91  { FR_CONF_OFFSET("name", fr_tls_cache_conf_t, id_name),
92  .dflt = "%{EAP-Type}%interpreter(server)", .quote = T_DOUBLE_QUOTED_STRING },
93  { FR_CONF_OFFSET("lifetime", fr_tls_cache_conf_t, lifetime), .dflt = "1d" },
94 
95  { FR_CONF_OFFSET("require_extended_master_secret", fr_tls_cache_conf_t, require_extms), .dflt = "yes" },
96  { FR_CONF_OFFSET("require_perfect_forward_secrecy", fr_tls_cache_conf_t, require_pfs), .dflt = "no" },
97 
98  { FR_CONF_OFFSET("session_ticket_key", fr_tls_cache_conf_t, session_ticket_key) },
99 
100  /*
101  * Deprecated
102  */
103  { FR_CONF_DEPRECATED("enable", fr_tls_cache_conf_t, NULL) },
104  { FR_CONF_DEPRECATED("max_entries", fr_tls_cache_conf_t, NULL) },
105  { FR_CONF_DEPRECATED("persist_dir", fr_tls_cache_conf_t, NULL) },
106 
108 };
109 
110 static conf_parser_t tls_chain_config[] = {
111  { FR_CONF_OFFSET("format", fr_tls_chain_conf_t, file_format),
112  .func = cf_table_parse_int,
113  .uctx = &(cf_table_parse_ctx_t){
114  .table = certificate_format_table,
115  .len = &certificate_format_table_len
116  },
117  .dflt = "pem" },
118  { FR_CONF_OFFSET_FLAGS("certificate_file", CONF_FLAG_FILE_INPUT | CONF_FLAG_FILE_EXISTS | CONF_FLAG_REQUIRED, fr_tls_chain_conf_t, certificate_file) },
119  { FR_CONF_OFFSET_FLAGS("private_key_password", CONF_FLAG_SECRET, fr_tls_chain_conf_t, password) },
120  { FR_CONF_OFFSET_FLAGS("private_key_file", CONF_FLAG_FILE_INPUT | CONF_FLAG_FILE_EXISTS | CONF_FLAG_REQUIRED, fr_tls_chain_conf_t, private_key_file) },
121 
122  { FR_CONF_OFFSET_FLAGS("ca_file", CONF_FLAG_FILE_INPUT | CONF_FLAG_MULTI, fr_tls_chain_conf_t, ca_files) },
123 
124  { FR_CONF_OFFSET("verify_mode", fr_tls_chain_conf_t, verify_mode),
125  .func = cf_table_parse_int,
126  .uctx = &(cf_table_parse_ctx_t){
127  .table = chain_verify_mode_table,
128  .len = &chain_verify_mode_table_len
129  },
130  .dflt = "hard" },
131  { FR_CONF_OFFSET("include_root_ca", fr_tls_chain_conf_t, include_root_ca), .dflt = "no" },
133 };
134 
135 static conf_parser_t tls_verify_config[] = {
136  { FR_CONF_OFFSET("mode", fr_tls_verify_conf_t, mode),
137  .func = cf_table_parse_int,
138  .uctx = &(cf_table_parse_ctx_t){
139  .table = verify_mode_table,
140  .len = &verify_mode_table_len
141  },
142  .dflt = "all" },
143  { FR_CONF_OFFSET("attribute_mode", fr_tls_verify_conf_t, attribute_mode),
144  .func = cf_table_parse_int,
145  .uctx = &(cf_table_parse_ctx_t){
146  .table = verify_mode_table,
147  .len = &verify_mode_table_len
148  },
149  .dflt = "client-and-issuer" },
150  { FR_CONF_OFFSET("check_crl", fr_tls_verify_conf_t, check_crl), .dflt = "no" },
151  { FR_CONF_OFFSET("allow_expired_crl", fr_tls_verify_conf_t, allow_expired_crl) },
152  { FR_CONF_OFFSET("allow_not_yet_valid_crl", fr_tls_verify_conf_t, allow_not_yet_valid_crl) },
154 };
155 
156 conf_parser_t fr_tls_server_config[] = {
157  { FR_CONF_OFFSET_TYPE_FLAGS("virtual_server", FR_TYPE_VOID, 0, fr_tls_conf_t, virtual_server), .func = virtual_server_cf_parse },
158 
159  { FR_CONF_OFFSET_SUBSECTION("chain", CONF_FLAG_MULTI, fr_tls_conf_t, chains, tls_chain_config),
160  .subcs_size = sizeof(fr_tls_chain_conf_t), .subcs_type = "fr_tls_chain_conf_t", .name2 = CF_IDENT_ANY },
161 
162  { FR_CONF_DEPRECATED("pem_file_type", fr_tls_conf_t, NULL) },
163  { FR_CONF_DEPRECATED("certificate_file", fr_tls_conf_t, NULL) },
164  { FR_CONF_DEPRECATED("private_key_password", fr_tls_conf_t, NULL) },
165  { FR_CONF_DEPRECATED("private_key_file", fr_tls_conf_t, NULL) },
166 
167  { FR_CONF_OFFSET("verify_depth", fr_tls_conf_t, verify_depth), .dflt = "0" },
168  { FR_CONF_OFFSET_FLAGS("ca_path", CONF_FLAG_FILE_INPUT, fr_tls_conf_t, ca_path) },
169  { FR_CONF_OFFSET_FLAGS("ca_file", CONF_FLAG_FILE_INPUT, fr_tls_conf_t, ca_file) },
170 
171 #ifdef PSK_MAX_IDENTITY_LEN
172  { FR_CONF_OFFSET("psk_identity", fr_tls_conf_t, psk_identity) },
173  { FR_CONF_OFFSET_FLAGS("psk_hexphrase", CONF_FLAG_SECRET, fr_tls_conf_t, psk_password) },
174  { FR_CONF_OFFSET("psk_query", fr_tls_conf_t, psk_query) },
175 #endif
176  { FR_CONF_OFFSET("keylog_file", fr_tls_conf_t, keylog_file) },
177 
178  { FR_CONF_OFFSET_FLAGS("dh_file", CONF_FLAG_FILE_INPUT, fr_tls_conf_t, dh_file) },
179  { FR_CONF_OFFSET("fragment_size", fr_tls_conf_t, fragment_size), .dflt = "1024" },
180  { FR_CONF_OFFSET("padding", fr_tls_conf_t, padding_block_size), },
181 
182  { FR_CONF_OFFSET("disable_single_dh_use", fr_tls_conf_t, disable_single_dh_use) },
183 
184  { FR_CONF_OFFSET("cipher_list", fr_tls_conf_t, cipher_list) },
185  { FR_CONF_OFFSET("cipher_server_preference", fr_tls_conf_t, cipher_server_preference), .dflt = "yes" },
186 #ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
187  { FR_CONF_OFFSET("allow_renegotiation", fr_tls_conf_t, allow_renegotiation), .dflt = "no" },
188 #endif
189 
190 #ifndef OPENSSL_NO_ECDH
191  { FR_CONF_OFFSET("ecdh_curve", fr_tls_conf_t, ecdh_curve), .dflt = "prime256v1" },
192 #endif
193  { FR_CONF_OFFSET("tls_max_version", fr_tls_conf_t, tls_max_version) },
194 
195  { FR_CONF_OFFSET("tls_min_version", fr_tls_conf_t, tls_min_version), .dflt = "1.2" },
196 
197  { FR_CONF_OFFSET_SUBSECTION("session", 0, fr_tls_conf_t, cache, tls_cache_config) },
198 
199  { FR_CONF_OFFSET_SUBSECTION("verify", 0, fr_tls_conf_t, verify, tls_verify_config) },
200 
201  { FR_CONF_DEPRECATED("check_cert_issuer", fr_tls_conf_t, check_cert_issuer) },
202  { FR_CONF_DEPRECATED("check_cert_cn", fr_tls_conf_t, check_cert_cn) },
204 };
205 
206 conf_parser_t fr_tls_client_config[] = {
207  { FR_CONF_OFFSET_SUBSECTION("chain", CONF_FLAG_OK_MISSING | CONF_FLAG_MULTI, fr_tls_conf_t, chains, tls_chain_config),
208  .subcs_size = sizeof(fr_tls_chain_conf_t), .subcs_type = "fr_tls_chain_conf_t" },
209 
210  { FR_CONF_DEPRECATED("pem_file_type", fr_tls_conf_t, NULL) },
211  { FR_CONF_DEPRECATED("certificate_file", fr_tls_conf_t, NULL) },
212  { FR_CONF_DEPRECATED("private_key_password", fr_tls_conf_t, NULL) },
213  { FR_CONF_DEPRECATED("private_key_file", fr_tls_conf_t, NULL) },
214 
215 #ifdef PSK_MAX_IDENTITY_LEN
216  { FR_CONF_OFFSET("psk_identity", fr_tls_conf_t, psk_identity) },
217  { FR_CONF_OFFSET_FLAGS("psk_hexphrase", CONF_FLAG_SECRET, fr_tls_conf_t, psk_password) },
218 #endif
219 
220  { FR_CONF_OFFSET("keylog_file", fr_tls_conf_t, keylog_file) },
221 
222  { FR_CONF_OFFSET("verify_depth", fr_tls_conf_t, verify_depth), .dflt = "0" },
223  { FR_CONF_OFFSET_FLAGS("ca_path", CONF_FLAG_FILE_INPUT, fr_tls_conf_t, ca_path) },
224 
225  { FR_CONF_OFFSET_FLAGS("ca_file", CONF_FLAG_FILE_INPUT, fr_tls_conf_t, ca_file) },
226  { FR_CONF_OFFSET("dh_file", fr_tls_conf_t, dh_file) },
227  { FR_CONF_OFFSET("random_file", fr_tls_conf_t, random_file) },
228  { FR_CONF_OFFSET("fragment_size", fr_tls_conf_t, fragment_size), .dflt = "1024" },
229 
230  { FR_CONF_OFFSET("cipher_list", fr_tls_conf_t, cipher_list) },
231 
232 #ifndef OPENSSL_NO_ECDH
233  { FR_CONF_OFFSET("ecdh_curve", fr_tls_conf_t, ecdh_curve), .dflt = "prime256v1" },
234 #endif
235 
236  { FR_CONF_OFFSET("tls_max_version", fr_tls_conf_t, tls_max_version) },
237 
238  { FR_CONF_OFFSET("tls_min_version", fr_tls_conf_t, tls_min_version), .dflt = "1.2" },
239 
240  { FR_CONF_DEPRECATED("check_cert_issuer", fr_tls_conf_t, check_cert_issuer) },
241  { FR_CONF_DEPRECATED("check_cert_cn", fr_tls_conf_t, check_cert_cn) },
243 };
244 
245 static int tls_conf_parse_cache_mode(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
246 {
247  fr_tls_conf_t *conf = talloc_get_type_abort((uint8_t *)parent - offsetof(fr_tls_conf_t, cache), fr_tls_conf_t);
248  int cache_mode;
249 
250  if (cf_table_parse_int(ctx, &cache_mode, parent, ci, rule) < 0) return -1;
251 
252  /*
253  * Ensure our virtual server contains the
254  * correct sections for the specified
255  * cache mode.
256  */
257  switch (cache_mode) {
258  case FR_TLS_CACHE_DISABLED:
259  case FR_TLS_CACHE_STATELESS:
260  break;
261 
262  case FR_TLS_CACHE_STATEFUL:
263  if (!conf->virtual_server) {
264  cf_log_err(ci, "A virtual_server must be set when cache.mode = \"stateful\"");
265  error:
266  return -1;
267  }
268 
269  if (!cf_section_find(conf->virtual_server, "load", "session")) {
270  cf_log_err(ci, "Specified virtual_server must contain a \"load session { ... }\" section "
271  "when cache.mode = \"stateful\"");
272  goto error;
273  }
274 
275  if (!cf_section_find(conf->virtual_server, "store", "session")) {
276  cf_log_err(ci, "Specified virtual_server must contain a \"store session { ... }\" section "
277  "when cache.mode = \"stateful\"");
278  goto error;
279  }
280 
281  if (!cf_section_find(conf->virtual_server, "clear", "session")) {
282  cf_log_err(ci, "Specified virtual_server must contain a \"clear session { ... }\" section "
283  "when cache.mode = \"stateful\"");
284  goto error;
285  }
286 
287  if (conf->tls_min_version >= (float)1.3) {
288  cf_log_err(ci, "cache.mode = \"stateful\" is not supported with tls_min_version >= 1.3");
289  goto error;
290  }
291  break;
292 
293  case FR_TLS_CACHE_AUTO:
294  if (!conf->virtual_server) {
295  WARN("A virtual_server must be provided for stateful caching. "
296  "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
297  cache_stateless:
298  cache_mode = FR_TLS_CACHE_STATELESS;
299  break;
300  }
301 
302  if (!cf_section_find(conf->virtual_server, "load", "session")) {
303  cf_log_warn(ci, "Specified virtual_server missing \"load session { ... }\" section. "
304  "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
305  goto cache_stateless;
306  }
307 
308  if (!cf_section_find(conf->virtual_server, "store", "session")) {
309  cf_log_warn(ci, "Specified virtual_server missing \"store session { ... }\" section. "
310  "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
311  goto cache_stateless;
312  }
313 
314  if (!cf_section_find(conf->virtual_server, "clear", "session")) {
315  cf_log_warn(ci, "Specified virtual_server missing \"clear cache { ... }\" section. "
316  "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
317  goto cache_stateless;
318  }
319 
320  if (conf->tls_min_version >= (float)1.3) {
321  cf_log_err(ci, "stateful session-resumption is not supported with tls_min_version >= 1.3. "
322  "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
323  goto error;
324  }
325  break;
326  }
327 
328  /*
329  * Generate random, ephemeral, session-ticket keys.
330  */
331  if (cache_mode & FR_TLS_CACHE_STATELESS) {
332  /*
333  * Fill the key with randomness if one
334  * wasn't specified by the user.
335  */
336  if (!conf->cache.session_ticket_key) {
337  MEM(conf->cache.session_ticket_key = talloc_array(conf, uint8_t, 256));
338  fr_rand_buffer(UNCONST(uint8_t *, conf->cache.session_ticket_key),
339  talloc_array_length(conf->cache.session_ticket_key));
340  }
341  }
342 
343  *((int *)out) = cache_mode;
344 
345  return 0;
346 }
347 
348 #ifdef __APPLE__
349 /*
350  * We don't want to put the private key password in eap.conf, so check
351  * for our special string which indicates we should get the password
352  * programmatically.
353  */
354 static char const *special_string = "Apple:UsecertAdmin";
355 
356 /** Use cert_admin to retrieve the password for the private key
357  *
358  */
359 static int conf_cert_admin_password(fr_tls_conf_t *conf)
360 {
361  size_t i, cnt;
362 
363  if (!conf->chains) return 0;
364 
365  cnt = talloc_array_length(conf->chains);
366  for (i = 0; i < cnt; i++) {
367  char cmd[256];
368  char *password;
369  long const max_password_len = 128;
370  FILE *cmd_pipe;
371 
372  if (!conf->chains[i]->password) continue;
373 
374  if (strncmp(conf->chains[i]->password, special_string, strlen(special_string)) != 0) continue;
375 
376  snprintf(cmd, sizeof(cmd) - 1, "/usr/sbin/certadmin --get-private-key-passphrase \"%s\"",
377  conf->chains[i]->private_key_file);
378 
379  DEBUG2("Getting private key passphrase using command \"%s\"", cmd);
380 
381  cmd_pipe = popen(cmd, "r");
382  if (!cmd_pipe) {
383  ERROR("%s command failed: Unable to get private_key_password", cmd);
384  ERROR("Error reading private_key_file %s", conf->chains[i]->private_key_file);
385  return -1;
386  }
387 
388  password = talloc_array(conf, char, max_password_len);
389  if (!password) {
390  ERROR("Can't allocate space for private_key_password");
391  ERROR("Error reading private_key_file %s", conf->chains[i]->private_key_file);
392  pclose(cmd_pipe);
393  return -1;
394  }
395 
396  fgets(password, max_password_len, cmd_pipe);
397  pclose(cmd_pipe);
398 
399  /* Get rid of newline at end of password. */
400  password[strlen(password) - 1] = '\0';
401 
402  DEBUG3("Password from command = \"%s\"", password);
403  talloc_const_free(conf->chains[i]->password);
404  conf->chains[i]->password = password;
405  }
406 
407  return 0;
408 }
409 #endif
410 
411 #ifdef HAVE_OPENSSL_OCSP_H
412 /*
413  * Create Global X509 revocation store and use it to verify
414  * OCSP responses
415  *
416  * - Load the trusted CAs
417  * - Load the trusted issuer certificates
418  */
419 static X509_STORE *conf_ocsp_revocation_store(fr_tls_conf_t *conf)
420 {
421  X509_STORE *store = NULL;
422 
423  store = X509_STORE_new();
424 
425  /* Load the CAs we trust */
426  if (conf->ca_file || conf->ca_path)
427  if (!X509_STORE_load_locations(store, conf->ca_file, conf->ca_path)) {
428  fr_tls_log(NULL, "Error reading Trusted root CA list \"%s\"", conf->ca_file);
429  X509_STORE_free(store);
430  return NULL;
431  }
432 
433 #ifdef X509_V_FLAG_CRL_CHECK_ALL
434  if (conf->verify.check_crl) X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
435 #endif
436 
437  return store;
438 }
439 #endif
440 
441 /*
442  * Free TLS client/server config
443  * Should not be called outside this code, as a callback is
444  * added to automatically free the data when the CONF_SECTION
445  * is freed.
446  */
447 static int _conf_server_free(fr_tls_conf_t *conf)
448 {
449  memset(conf, 0, sizeof(*conf));
450  return 0;
451 }
452 
453 fr_tls_conf_t *fr_tls_conf_alloc(TALLOC_CTX *ctx)
454 {
455  fr_tls_conf_t *conf;
456 
457  MEM(conf = talloc_zero(ctx, fr_tls_conf_t));
458  talloc_set_destructor(conf, _conf_server_free);
459 
460  return conf;
461 }
462 
463 fr_tls_conf_t *fr_tls_conf_parse_server(CONF_SECTION *cs)
464 {
465  fr_tls_conf_t *conf;
466 
467  /*
468  * If cs has already been parsed there should be a cached copy
469  * of conf already stored, so just return that.
470  */
471  conf = cf_data_value(cf_data_find(cs, fr_tls_conf_t, NULL));
472  if (conf) {
473  DEBUG("Using cached TLS configuration from previous invocation");
474  return conf;
475  }
476 
477  if (cf_section_rules_push(cs, fr_tls_server_config) < 0) return NULL;
478 
479  conf = fr_tls_conf_alloc(cs);
480 
481  if ((cf_section_parse(conf, conf, cs) < 0) ||
482  (cf_section_parse_pass2(conf, cs) < 0)) {
483 #ifdef __APPLE__
484  error:
485 #endif
486  talloc_free(conf);
487  return NULL;
488  }
489 
490  /*
491  * Save people from their own stupidity.
492  */
493  if (conf->fragment_size < 100) conf->fragment_size = 100;
494 
495  FR_INTEGER_BOUND_CHECK("padding", conf->padding_block_size, <=, SSL3_RT_MAX_PLAIN_LENGTH);
496 
497 #ifdef __APPLE__
498  if (conf_cert_admin_password(conf) < 0) goto error;
499 #endif
500 
501  /*
502  * Cache conf in cs in case we're asked to parse this again.
503  */
504  cf_data_add(cs, conf, NULL, false);
505 
506  return conf;
507 }
508 
509 fr_tls_conf_t *fr_tls_conf_parse_client(CONF_SECTION *cs)
510 {
511  fr_tls_conf_t *conf;
512 
513  conf = cf_data_value(cf_data_find(cs, fr_tls_conf_t, NULL));
514  if (conf) {
515  DEBUG2("Using cached TLS configuration from previous invocation");
516  return conf;
517  }
518 
519  if (cf_section_rules_push(cs, fr_tls_client_config) < 0) return NULL;
520 
521  conf = fr_tls_conf_alloc(cs);
522 
523  if ((cf_section_parse(conf, conf, cs) < 0) ||
524  (cf_section_parse_pass2(conf, cs) < 0)) {
525 #ifdef __APPLE__
526  error:
527 #endif
528  talloc_free(conf);
529  return NULL;
530  }
531 
532  /*
533  * Save people from their own stupidity.
534  */
535  if (conf->fragment_size < 100) conf->fragment_size = 100;
536 
537  /*
538  * Initialize TLS
539  */
540 #ifdef __APPLE__
541  if (conf_cert_admin_password(conf) < 0) goto error;
542 #endif
543 
544  cf_data_add(cs, conf, NULL, false);
545 
546  return conf;
547 }
548 #endif /* WITH_TLS */
#define store(_store, _var)
Definition: atomic_queue.h:48
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition: build.h:165
#define USES_APPLE_DEPRECATED_API
Definition: build.h:468
#define RCSID(id)
Definition: build.h:481
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
#define NUM_ELEMENTS(_t)
Definition: build.h:335
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
Definition: cf_parse.c:985
int cf_table_parse_int(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic function for parsing conf pair values as int.
Definition: cf_parse.c:1474
int cf_section_parse_pass2(void *base, CONF_SECTION *cs)
Fixup xlat expansions and attributes.
Definition: cf_parse.c:1163
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:627
#define FR_CONF_DEPRECATED(_name, _struct, _field)
conf_parser_t entry which raises an error if a matching CONF_PAIR is found
Definition: cf_parse.h:385
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
Definition: cf_parse.h:487
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:268
#define cf_section_rules_push(_cs, _rule)
Definition: cf_parse.h:659
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:256
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
Definition: cf_parse.h:297
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition: cf_parse.h:405
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
Definition: cf_parse.h:419
@ CONF_FLAG_SECRET
Only print value if debug level >= 3.
Definition: cf_parse.h:409
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Definition: cf_parse.h:411
@ CONF_FLAG_OK_MISSING
OK if it's missing.
Definition: cf_parse.h:427
@ CONF_FLAG_FILE_EXISTS
File matching value must exist.
Definition: cf_parse.h:422
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:241
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:564
Common header for all CONF_* types.
Definition: cf_priv.h:49
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:101
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
Definition: cf_util.c:1028
void * cf_data_value(CONF_DATA const *cd)
Return the user assigned value of CONF_DATA.
Definition: cf_util.c:1763
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:289
#define cf_data_add(_cf, _data, _name, _free)
Definition: cf_util.h:255
#define cf_data_find(_cf, _type, _name)
Definition: cf_util.h:244
#define cf_log_warn(_cf, _fmt,...)
Definition: cf_util.h:290
#define CF_IDENT_ANY
Definition: cf_util.h:78
#define ERROR(fmt,...)
Definition: dhcpclient.c:41
#define DEBUG(fmt,...)
Definition: dhcpclient.c:39
#define DEBUG3(_fmt,...)
Definition: log.h:266
talloc_free(reap)
@ FR_TYPE_VOID
User data.
Definition: merged_model.c:127
unsigned char uint8_t
Definition: merged_model.c:30
static int _conf_server_free(fr_tls_conf_t *conf)
Definition: conf.c:73
#define DEBUG2(fmt,...)
Definition: radclient.h:43
#define WARN(fmt,...)
Definition: radclient.h:47
static rs_t * conf
Definition: radsniff.c:53
void fr_rand_buffer(void *start, size_t length)
Definition: rand.c:126
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:689
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
An element in a lexicographically sorted array of name to num mappings.
Definition: table.h:49
static int talloc_const_free(void const *ptr)
Free const'd memory.
Definition: talloc.h:224
@ T_DOUBLE_QUOTED_STRING
Definition: token.h:121
static fr_slen_t parent
Definition: pair.h:851
static size_t char ** out
Definition: value.h:997
int virtual_server_cf_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
Wrapper for the config parser to allow pass1 resolution of virtual servers.