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: 421cf4e8ee42fb00dc3a6add203353a4f07b246e $
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: 421cf4e8ee42fb00dc3a6add203353a4f07b246e $")
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 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
96  { FR_CONF_OFFSET("require_extended_master_secret", fr_tls_cache_conf_t, require_extms), .dflt = "yes" },
97  { FR_CONF_OFFSET("require_perfect_forward_secrecy", fr_tls_cache_conf_t, require_pfs), .dflt = "no" },
98 #endif
99 
100  { FR_CONF_OFFSET("session_ticket_key", fr_tls_cache_conf_t, session_ticket_key) },
101 
102  /*
103  * Deprecated
104  */
105  { FR_CONF_DEPRECATED("enable", fr_tls_cache_conf_t, NULL) },
106  { FR_CONF_DEPRECATED("max_entries", fr_tls_cache_conf_t, NULL) },
107  { FR_CONF_DEPRECATED("persist_dir", fr_tls_cache_conf_t, NULL) },
108 
110 };
111 
112 static conf_parser_t tls_chain_config[] = {
113  { FR_CONF_OFFSET("format", fr_tls_chain_conf_t, file_format),
114  .func = cf_table_parse_int,
115  .uctx = &(cf_table_parse_ctx_t){
116  .table = certificate_format_table,
117  .len = &certificate_format_table_len
118  },
119  .dflt = "pem" },
120  { FR_CONF_OFFSET_FLAGS("certificate_file", CONF_FLAG_FILE_INPUT | CONF_FLAG_FILE_EXISTS | CONF_FLAG_REQUIRED, fr_tls_chain_conf_t, certificate_file) },
121  { FR_CONF_OFFSET_FLAGS("private_key_password", CONF_FLAG_SECRET, fr_tls_chain_conf_t, password) },
122  { 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) },
123 
124  { FR_CONF_OFFSET_FLAGS("ca_file", CONF_FLAG_FILE_INPUT | CONF_FLAG_MULTI, fr_tls_chain_conf_t, ca_files) },
125 
126  { FR_CONF_OFFSET("verify_mode", fr_tls_chain_conf_t, verify_mode),
127  .func = cf_table_parse_int,
128  .uctx = &(cf_table_parse_ctx_t){
129  .table = chain_verify_mode_table,
130  .len = &chain_verify_mode_table_len
131  },
132  .dflt = "hard" },
133  { FR_CONF_OFFSET("include_root_ca", fr_tls_chain_conf_t, include_root_ca), .dflt = "no" },
135 };
136 
137 static conf_parser_t tls_verify_config[] = {
138  { FR_CONF_OFFSET("mode", fr_tls_verify_conf_t, mode),
139  .func = cf_table_parse_int,
140  .uctx = &(cf_table_parse_ctx_t){
141  .table = verify_mode_table,
142  .len = &verify_mode_table_len
143  },
144  .dflt = "all" },
145  { FR_CONF_OFFSET("attribute_mode", fr_tls_verify_conf_t, attribute_mode),
146  .func = cf_table_parse_int,
147  .uctx = &(cf_table_parse_ctx_t){
148  .table = verify_mode_table,
149  .len = &verify_mode_table_len
150  },
151  .dflt = "client-and-issuer" },
152  { FR_CONF_OFFSET("check_crl", fr_tls_verify_conf_t, check_crl), .dflt = "no" },
153  { FR_CONF_OFFSET("allow_expired_crl", fr_tls_verify_conf_t, allow_expired_crl) },
154  { FR_CONF_OFFSET("allow_not_yet_valid_crl", fr_tls_verify_conf_t, allow_not_yet_valid_crl) },
156 };
157 
158 conf_parser_t fr_tls_server_config[] = {
159  { FR_CONF_OFFSET_TYPE_FLAGS("virtual_server", FR_TYPE_VOID, 0, fr_tls_conf_t, virtual_server), .func = virtual_server_cf_parse },
160 
161  { FR_CONF_OFFSET_SUBSECTION("chain", CONF_FLAG_MULTI, fr_tls_conf_t, chains, tls_chain_config),
162  .subcs_size = sizeof(fr_tls_chain_conf_t), .subcs_type = "fr_tls_chain_conf_t", .name2 = CF_IDENT_ANY },
163 
164  { FR_CONF_DEPRECATED("pem_file_type", fr_tls_conf_t, NULL) },
165  { FR_CONF_DEPRECATED("certificate_file", fr_tls_conf_t, NULL) },
166  { FR_CONF_DEPRECATED("private_key_password", fr_tls_conf_t, NULL) },
167  { FR_CONF_DEPRECATED("private_key_file", fr_tls_conf_t, NULL) },
168 
169  { FR_CONF_OFFSET("verify_depth", fr_tls_conf_t, verify_depth), .dflt = "0" },
170  { FR_CONF_OFFSET_FLAGS("ca_path", CONF_FLAG_FILE_INPUT, fr_tls_conf_t, ca_path) },
171  { FR_CONF_OFFSET_FLAGS("ca_file", CONF_FLAG_FILE_INPUT, fr_tls_conf_t, ca_file) },
172 
173 #ifdef PSK_MAX_IDENTITY_LEN
174  { FR_CONF_OFFSET("psk_identity", fr_tls_conf_t, psk_identity) },
175  { FR_CONF_OFFSET_FLAGS("psk_hexphrase", CONF_FLAG_SECRET, fr_tls_conf_t, psk_password) },
176  { FR_CONF_OFFSET("psk_query", fr_tls_conf_t, psk_query) },
177 #endif
178  { FR_CONF_OFFSET("keylog_file", fr_tls_conf_t, keylog_file) },
179 
180  { FR_CONF_OFFSET_FLAGS("dh_file", CONF_FLAG_FILE_INPUT, fr_tls_conf_t, dh_file) },
181  { FR_CONF_OFFSET("fragment_size", fr_tls_conf_t, fragment_size), .dflt = "1024" },
182  { FR_CONF_OFFSET("padding", fr_tls_conf_t, padding_block_size), },
183 
184  { FR_CONF_OFFSET("disable_single_dh_use", fr_tls_conf_t, disable_single_dh_use) },
185 
186  { FR_CONF_OFFSET("cipher_list", fr_tls_conf_t, cipher_list) },
187  { FR_CONF_OFFSET("cipher_server_preference", fr_tls_conf_t, cipher_server_preference), .dflt = "yes" },
188 #ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
189  { FR_CONF_OFFSET("allow_renegotiation", fr_tls_conf_t, allow_renegotiation), .dflt = "no" },
190 #endif
191 
192 #ifndef OPENSSL_NO_ECDH
193  { FR_CONF_OFFSET("ecdh_curve", fr_tls_conf_t, ecdh_curve), .dflt = "prime256v1" },
194 #endif
195  { FR_CONF_OFFSET("tls_max_version", fr_tls_conf_t, tls_max_version) },
196 
197  { FR_CONF_OFFSET("tls_min_version", fr_tls_conf_t, tls_min_version), .dflt = "1.2" },
198 
199  { FR_CONF_OFFSET_SUBSECTION("session", 0, fr_tls_conf_t, cache, tls_cache_config) },
200 
201  { FR_CONF_OFFSET_SUBSECTION("verify", 0, fr_tls_conf_t, verify, tls_verify_config) },
202 
203  { FR_CONF_DEPRECATED("check_cert_issuer", fr_tls_conf_t, check_cert_issuer) },
204  { FR_CONF_DEPRECATED("check_cert_cn", fr_tls_conf_t, check_cert_cn) },
206 };
207 
208 conf_parser_t fr_tls_client_config[] = {
209  { FR_CONF_OFFSET_SUBSECTION("chain", CONF_FLAG_OK_MISSING | CONF_FLAG_MULTI, fr_tls_conf_t, chains, tls_chain_config),
210  .subcs_size = sizeof(fr_tls_chain_conf_t), .subcs_type = "fr_tls_chain_conf_t" },
211 
212  { FR_CONF_DEPRECATED("pem_file_type", fr_tls_conf_t, NULL) },
213  { FR_CONF_DEPRECATED("certificate_file", fr_tls_conf_t, NULL) },
214  { FR_CONF_DEPRECATED("private_key_password", fr_tls_conf_t, NULL) },
215  { FR_CONF_DEPRECATED("private_key_file", fr_tls_conf_t, NULL) },
216 
217 #ifdef PSK_MAX_IDENTITY_LEN
218  { FR_CONF_OFFSET("psk_identity", fr_tls_conf_t, psk_identity) },
219  { FR_CONF_OFFSET_FLAGS("psk_hexphrase", CONF_FLAG_SECRET, fr_tls_conf_t, psk_password) },
220 #endif
221 
222  { FR_CONF_OFFSET("keylog_file", fr_tls_conf_t, keylog_file) },
223 
224  { FR_CONF_OFFSET("verify_depth", fr_tls_conf_t, verify_depth), .dflt = "0" },
225  { FR_CONF_OFFSET_FLAGS("ca_path", CONF_FLAG_FILE_INPUT, fr_tls_conf_t, ca_path) },
226 
227  { FR_CONF_OFFSET_FLAGS("ca_file", CONF_FLAG_FILE_INPUT, fr_tls_conf_t, ca_file) },
228  { FR_CONF_OFFSET("dh_file", fr_tls_conf_t, dh_file) },
229  { FR_CONF_OFFSET("random_file", fr_tls_conf_t, random_file) },
230  { FR_CONF_OFFSET("fragment_size", fr_tls_conf_t, fragment_size), .dflt = "1024" },
231 
232  { FR_CONF_OFFSET("cipher_list", fr_tls_conf_t, cipher_list) },
233 
234 #ifndef OPENSSL_NO_ECDH
235  { FR_CONF_OFFSET("ecdh_curve", fr_tls_conf_t, ecdh_curve), .dflt = "prime256v1" },
236 #endif
237 
238  { FR_CONF_OFFSET("tls_max_version", fr_tls_conf_t, tls_max_version) },
239 
240  { FR_CONF_OFFSET("tls_min_version", fr_tls_conf_t, tls_min_version), .dflt = "1.2" },
241 
242  { FR_CONF_DEPRECATED("check_cert_issuer", fr_tls_conf_t, check_cert_issuer) },
243  { FR_CONF_DEPRECATED("check_cert_cn", fr_tls_conf_t, check_cert_cn) },
245 };
246 
247 static int tls_conf_parse_cache_mode(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
248 {
249  fr_tls_conf_t *conf = talloc_get_type_abort((uint8_t *)parent - offsetof(fr_tls_conf_t, cache), fr_tls_conf_t);
250  int cache_mode;
251 
252  if (cf_table_parse_int(ctx, &cache_mode, parent, ci, rule) < 0) return -1;
253 
254  /*
255  * Ensure our virtual server contains the
256  * correct sections for the specified
257  * cache mode.
258  */
259  switch (cache_mode) {
260  case FR_TLS_CACHE_DISABLED:
261  case FR_TLS_CACHE_STATELESS:
262  break;
263 
264  case FR_TLS_CACHE_STATEFUL:
265  if (!conf->virtual_server) {
266  cf_log_err(ci, "A virtual_server must be set when cache.mode = \"stateful\"");
267  error:
268  return -1;
269  }
270 
271  if (!cf_section_find(conf->virtual_server, "load", "session")) {
272  cf_log_err(ci, "Specified virtual_server must contain a \"load session { ... }\" section "
273  "when cache.mode = \"stateful\"");
274  goto error;
275  }
276 
277  if (!cf_section_find(conf->virtual_server, "store", "session")) {
278  cf_log_err(ci, "Specified virtual_server must contain a \"store session { ... }\" section "
279  "when cache.mode = \"stateful\"");
280  goto error;
281  }
282 
283  if (!cf_section_find(conf->virtual_server, "clear", "session")) {
284  cf_log_err(ci, "Specified virtual_server must contain a \"clear session { ... }\" section "
285  "when cache.mode = \"stateful\"");
286  goto error;
287  }
288 
289  if (conf->tls_min_version >= (float)1.3) {
290  cf_log_err(ci, "cache.mode = \"stateful\" is not supported with tls_min_version >= 1.3");
291  goto error;
292  }
293  break;
294 
295  case FR_TLS_CACHE_AUTO:
296  if (!conf->virtual_server) {
297  WARN("A virtual_server must be provided for stateful caching. "
298  "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
299  cache_stateless:
300  conf->cache.mode = FR_TLS_CACHE_STATELESS;
301  break;
302  }
303 
304  if (!cf_section_find(conf->virtual_server, "load", "session")) {
305  cf_log_warn(ci, "Specified virtual_server missing \"load session { ... }\" section. "
306  "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
307  goto cache_stateless;
308  }
309 
310  if (!cf_section_find(conf->virtual_server, "store", "session")) {
311  cf_log_warn(ci, "Specified virtual_server missing \"store session { ... }\" section. "
312  "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
313  goto cache_stateless;
314  }
315 
316  if (!cf_section_find(conf->virtual_server, "clear", "session")) {
317  cf_log_warn(ci, "Specified virtual_server missing \"clear cache { ... }\" section. "
318  "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
319  goto cache_stateless;
320  }
321 
322  if (conf->tls_min_version >= (float)1.3) {
323  cf_log_err(ci, "stateful session-resumption is not supported with tls_min_version >= 1.3. "
324  "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
325  goto error;
326  }
327  break;
328  }
329 
330  /*
331  * Generate random, ephemeral, session-ticket keys.
332  */
333  if (cache_mode & FR_TLS_CACHE_STATELESS) {
334  /*
335  * Fill the key with randomness if one
336  * wasn't specified by the user.
337  */
338  if (!conf->cache.session_ticket_key) {
339  MEM(conf->cache.session_ticket_key = talloc_array(conf, uint8_t, 256));
340  fr_rand_buffer(UNCONST(uint8_t *, conf->cache.session_ticket_key),
341  talloc_array_length(conf->cache.session_ticket_key));
342  }
343  }
344 
345  *((int *)out) = cache_mode;
346 
347  return 0;
348 }
349 
350 #ifdef __APPLE__
351 /*
352  * We don't want to put the private key password in eap.conf, so check
353  * for our special string which indicates we should get the password
354  * programmatically.
355  */
356 static char const *special_string = "Apple:UsecertAdmin";
357 
358 /** Use cert_admin to retrieve the password for the private key
359  *
360  */
361 static int conf_cert_admin_password(fr_tls_conf_t *conf)
362 {
363  size_t i, cnt;
364 
365  if (!conf->chains) return 0;
366 
367  cnt = talloc_array_length(conf->chains);
368  for (i = 0; i < cnt; i++) {
369  char cmd[256];
370  char *password;
371  long const max_password_len = 128;
372  FILE *cmd_pipe;
373 
374  if (!conf->chains[i]->password) continue;
375 
376  if (strncmp(conf->chains[i]->password, special_string, strlen(special_string)) != 0) continue;
377 
378  snprintf(cmd, sizeof(cmd) - 1, "/usr/sbin/certadmin --get-private-key-passphrase \"%s\"",
379  conf->chains[i]->private_key_file);
380 
381  DEBUG2("Getting private key passphrase using command \"%s\"", cmd);
382 
383  cmd_pipe = popen(cmd, "r");
384  if (!cmd_pipe) {
385  ERROR("%s command failed: Unable to get private_key_password", cmd);
386  ERROR("Error reading private_key_file %s", conf->chains[i]->private_key_file);
387  return -1;
388  }
389 
390  password = talloc_array(conf, char, max_password_len);
391  if (!password) {
392  ERROR("Can't allocate space for private_key_password");
393  ERROR("Error reading private_key_file %s", conf->chains[i]->private_key_file);
394  pclose(cmd_pipe);
395  return -1;
396  }
397 
398  fgets(password, max_password_len, cmd_pipe);
399  pclose(cmd_pipe);
400 
401  /* Get rid of newline at end of password. */
402  password[strlen(password) - 1] = '\0';
403 
404  DEBUG3("Password from command = \"%s\"", password);
405  talloc_const_free(conf->chains[i]->password);
406  conf->chains[i]->password = password;
407  }
408 
409  return 0;
410 }
411 #endif
412 
413 #ifdef HAVE_OPENSSL_OCSP_H
414 /*
415  * Create Global X509 revocation store and use it to verify
416  * OCSP responses
417  *
418  * - Load the trusted CAs
419  * - Load the trusted issuer certificates
420  */
421 static X509_STORE *conf_ocsp_revocation_store(fr_tls_conf_t *conf)
422 {
423  X509_STORE *store = NULL;
424 
425  store = X509_STORE_new();
426 
427  /* Load the CAs we trust */
428  if (conf->ca_file || conf->ca_path)
429  if (!X509_STORE_load_locations(store, conf->ca_file, conf->ca_path)) {
430  fr_tls_log(NULL, "Error reading Trusted root CA list \"%s\"", conf->ca_file);
431  X509_STORE_free(store);
432  return NULL;
433  }
434 
435 #ifdef X509_V_FLAG_CRL_CHECK_ALL
436  if (conf->verify.check_crl) X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
437 #endif
438 
439  return store;
440 }
441 #endif
442 
443 /*
444  * Free TLS client/server config
445  * Should not be called outside this code, as a callback is
446  * added to automatically free the data when the CONF_SECTION
447  * is freed.
448  */
449 static int _conf_server_free(fr_tls_conf_t *conf)
450 {
451  memset(conf, 0, sizeof(*conf));
452  return 0;
453 }
454 
455 fr_tls_conf_t *fr_tls_conf_alloc(TALLOC_CTX *ctx)
456 {
457  fr_tls_conf_t *conf;
458 
459  MEM(conf = talloc_zero(ctx, fr_tls_conf_t));
460  talloc_set_destructor(conf, _conf_server_free);
461 
462  return conf;
463 }
464 
465 fr_tls_conf_t *fr_tls_conf_parse_server(CONF_SECTION *cs)
466 {
467  fr_tls_conf_t *conf;
468 
469  /*
470  * If cs has already been parsed there should be a cached copy
471  * of conf already stored, so just return that.
472  */
473  conf = cf_data_value(cf_data_find(cs, fr_tls_conf_t, NULL));
474  if (conf) {
475  DEBUG("Using cached TLS configuration from previous invocation");
476  return conf;
477  }
478 
479  if (cf_section_rules_push(cs, fr_tls_server_config) < 0) return NULL;
480 
481  conf = fr_tls_conf_alloc(cs);
482 
483  if ((cf_section_parse(conf, conf, cs) < 0) ||
484  (cf_section_parse_pass2(conf, cs) < 0)) {
485 #ifdef __APPLE__
486  error:
487 #endif
488  talloc_free(conf);
489  return NULL;
490  }
491 
492  /*
493  * Save people from their own stupidity.
494  */
495  if (conf->fragment_size < 100) conf->fragment_size = 100;
496 
497  FR_INTEGER_BOUND_CHECK("padding", conf->padding_block_size, <=, SSL3_RT_MAX_PLAIN_LENGTH);
498 
499 #ifdef __APPLE__
500  if (conf_cert_admin_password(conf) < 0) goto error;
501 #endif
502 
503  /*
504  * Cache conf in cs in case we're asked to parse this again.
505  */
506  cf_data_add(cs, conf, NULL, false);
507 
508  return conf;
509 }
510 
511 fr_tls_conf_t *fr_tls_conf_parse_client(CONF_SECTION *cs)
512 {
513  fr_tls_conf_t *conf;
514 
515  conf = cf_data_value(cf_data_find(cs, fr_tls_conf_t, NULL));
516  if (conf) {
517  DEBUG2("Using cached TLS configuration from previous invocation");
518  return conf;
519  }
520 
521  if (cf_section_rules_push(cs, fr_tls_client_config) < 0) return NULL;
522 
523  conf = fr_tls_conf_alloc(cs);
524 
525  if ((cf_section_parse(conf, conf, cs) < 0) ||
526  (cf_section_parse_pass2(conf, cs) < 0)) {
527 #ifdef __APPLE__
528  error:
529 #endif
530  talloc_free(conf);
531  return NULL;
532  }
533 
534  /*
535  * Save people from their own stupidity.
536  */
537  if (conf->fragment_size < 100) conf->fragment_size = 100;
538 
539  /*
540  * Initialize TLS
541  */
542 #ifdef __APPLE__
543  if (conf_cert_admin_password(conf) < 0) goto error;
544 #endif
545 
546  cf_data_add(cs, conf, NULL, false);
547 
548  return conf;
549 }
550 #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:431
#define RCSID(id)
Definition: build.h:444
#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:626
#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:486
#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:658
#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:406
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
Definition: cf_parse.h:420
@ CONF_FLAG_SECRET
Only print value if debug level >= 3.
Definition: cf_parse.h:410
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Definition: cf_parse.h:412
@ CONF_FLAG_OK_MISSING
OK if it's missing.
Definition: cf_parse.h:428
@ CONF_FLAG_FILE_EXISTS
File matching value must exist.
Definition: cf_parse.h:423
#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:563
Common header for all CONF_* types.
Definition: cf_priv.h:49
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
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:970
void * cf_data_value(CONF_DATA const *cd)
Return the user assigned value of CONF_DATA.
Definition: cf_util.c:1680
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:265
#define cf_data_add(_cf, _data, _name, _free)
Definition: cf_util.h:231
#define cf_data_find(_cf, _type, _name)
Definition: cf_util.h:220
#define cf_log_warn(_cf, _fmt,...)
Definition: cf_util.h:266
#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:45
static int talloc_const_free(void const *ptr)
Free const'd memory.
Definition: talloc.h:212
@ T_DOUBLE_QUOTED_STRING
Definition: token.h:121
static fr_slen_t parent
Definition: pair.h:844
static size_t char ** out
Definition: value.h:984
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.