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