The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 73c00c72d858a536490c98919ea9da9ab31dab58 $
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: 73c00c72d858a536490c98919ea9da9ab31dab58 $")
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("check_crl", fr_tls_verify_conf_t, check_crl), .dflt = "no" },
152 { FR_CONF_OFFSET("allow_expired_crl", fr_tls_verify_conf_t, allow_expired_crl) },
153 { FR_CONF_OFFSET("allow_not_yet_valid_crl", fr_tls_verify_conf_t, allow_not_yet_valid_crl) },
154 { FR_CONF_OFFSET("der_decode", fr_tls_verify_conf_t, der_decode) },
156};
157
158conf_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 = tls_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_READABLE, fr_tls_conf_t, ca_path) },
171 { FR_CONF_OFFSET_FLAGS("ca_file", CONF_FLAG_FILE_READABLE, 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_READABLE, 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#ifdef TLS1_3_VERSION
188 { FR_CONF_OFFSET("cipher_suites", fr_tls_conf_t, cipher_suites) },
189#endif
190 { FR_CONF_OFFSET("cipher_server_preference", fr_tls_conf_t, cipher_server_preference), .dflt = "yes" },
191#ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
192 { FR_CONF_OFFSET("allow_renegotiation", fr_tls_conf_t, allow_renegotiation), .dflt = "no" },
193#endif
194
195#ifndef OPENSSL_NO_ECDH
196 { FR_CONF_OFFSET("ecdh_curve", fr_tls_conf_t, ecdh_curve), .dflt = "prime256v1" },
197#endif
198 { FR_CONF_OFFSET("tls_max_version", fr_tls_conf_t, tls_max_version) },
199
200 { FR_CONF_OFFSET("tls_min_version", fr_tls_conf_t, tls_min_version), .dflt = "1.2" },
201
202 { FR_CONF_OFFSET("client_hello_parse", fr_tls_conf_t, client_hello_parse )},
203
204 { FR_CONF_OFFSET_SUBSECTION("session", 0, fr_tls_conf_t, cache, tls_cache_config) },
205
206 { FR_CONF_OFFSET_SUBSECTION("verify", 0, fr_tls_conf_t, verify, tls_verify_config) },
207
208 { FR_CONF_DEPRECATED("check_cert_issuer", fr_tls_conf_t, check_cert_issuer) },
209 { FR_CONF_DEPRECATED("check_cert_cn", fr_tls_conf_t, check_cert_cn) },
211};
212
213conf_parser_t fr_tls_client_config[] = {
214 { FR_CONF_OFFSET_SUBSECTION("chain", CONF_FLAG_OK_MISSING | CONF_FLAG_MULTI, fr_tls_conf_t, chains, tls_chain_config),
215 .subcs_size = sizeof(fr_tls_chain_conf_t), .subcs_type = "fr_tls_chain_conf_t" },
216
217 { FR_CONF_DEPRECATED("pem_file_type", fr_tls_conf_t, NULL) },
218 { FR_CONF_DEPRECATED("certificate_file", fr_tls_conf_t, NULL) },
219 { FR_CONF_DEPRECATED("private_key_password", fr_tls_conf_t, NULL) },
220 { FR_CONF_DEPRECATED("private_key_file", fr_tls_conf_t, NULL) },
221
222#ifdef PSK_MAX_IDENTITY_LEN
223 { FR_CONF_OFFSET("psk_identity", fr_tls_conf_t, psk_identity) },
224 { FR_CONF_OFFSET_FLAGS("psk_hexphrase", CONF_FLAG_SECRET, fr_tls_conf_t, psk_password) },
225#endif
226
227 { FR_CONF_OFFSET("keylog_file", fr_tls_conf_t, keylog_file) },
228
229 { FR_CONF_OFFSET("verify_depth", fr_tls_conf_t, verify_depth), .dflt = "0" },
230 { FR_CONF_OFFSET_FLAGS("ca_path", CONF_FLAG_FILE_READABLE, fr_tls_conf_t, ca_path) },
231
232 { FR_CONF_OFFSET_FLAGS("ca_file", CONF_FLAG_FILE_READABLE, fr_tls_conf_t, ca_file) },
233 { FR_CONF_OFFSET("dh_file", fr_tls_conf_t, dh_file) },
234 { FR_CONF_OFFSET("random_file", fr_tls_conf_t, random_file) },
235 { FR_CONF_OFFSET("fragment_size", fr_tls_conf_t, fragment_size), .dflt = "1024" },
236
237 { FR_CONF_OFFSET("cipher_list", fr_tls_conf_t, cipher_list) },
238#ifdef TLS1_3_VERSION
239 { FR_CONF_OFFSET("cipher_suites", fr_tls_conf_t, cipher_suites) },
240#endif
241
242#ifndef OPENSSL_NO_ECDH
243 { FR_CONF_OFFSET("ecdh_curve", fr_tls_conf_t, ecdh_curve), .dflt = "prime256v1" },
244#endif
245
246 { FR_CONF_OFFSET("tls_max_version", fr_tls_conf_t, tls_max_version) },
247
248 { FR_CONF_OFFSET("tls_min_version", fr_tls_conf_t, tls_min_version), .dflt = "1.2" },
249
250 { FR_CONF_DEPRECATED("check_cert_issuer", fr_tls_conf_t, check_cert_issuer) },
251 { FR_CONF_DEPRECATED("check_cert_cn", fr_tls_conf_t, check_cert_cn) },
253};
254
255static int tls_virtual_server_cf_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
256{
257 fr_tls_conf_t *conf = talloc_get_type_abort(parent, fr_tls_conf_t);
258 virtual_server_t const *vs = NULL;
259
260 if (virtual_server_cf_parse(ctx, &vs, parent, ci, rule) < 0) return -1;
261
262 if (!vs) return 0;
263
264 /*
265 * `out` points to conf->virtual_server
266 */
267 *((CONF_SECTION const **)out) = virtual_server_cs(vs);
268 conf->verify_certificate = cf_section_find(conf->virtual_server, "verify", "certificate") ? true : false;
269 conf->new_session = cf_section_find(conf->virtual_server, "new", "session") ? true : false;
270 conf->establish_session = cf_section_find(conf->virtual_server, "establish", "session") ? true : false;
271 return 0;
272}
273
274static int tls_conf_parse_cache_mode(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
275{
276 fr_tls_conf_t *conf = talloc_get_type_abort((uint8_t *)parent - offsetof(fr_tls_conf_t, cache), fr_tls_conf_t);
277 int cache_mode;
278
279 if (cf_table_parse_int(ctx, &cache_mode, parent, ci, rule) < 0) return -1;
280
281 /*
282 * Ensure our virtual server contains the
283 * correct sections for the specified
284 * cache mode.
285 */
286 switch (cache_mode) {
287 case FR_TLS_CACHE_DISABLED:
288 case FR_TLS_CACHE_STATELESS:
289 break;
290
291 case FR_TLS_CACHE_STATEFUL:
292 if (!conf->virtual_server) {
293 cf_log_err(ci, "A virtual_server must be set when cache.mode = \"stateful\"");
294 error:
295 return -1;
296 }
297
298 if (!cf_section_find(conf->virtual_server, "load", "session")) {
299 cf_log_err(ci, "Specified virtual_server must contain a \"load session { ... }\" section "
300 "when cache.mode = \"stateful\"");
301 goto error;
302 }
303
304 if (!cf_section_find(conf->virtual_server, "store", "session")) {
305 cf_log_err(ci, "Specified virtual_server must contain a \"store session { ... }\" section "
306 "when cache.mode = \"stateful\"");
307 goto error;
308 }
309
310 if (!cf_section_find(conf->virtual_server, "clear", "session")) {
311 cf_log_err(ci, "Specified virtual_server must contain a \"clear session { ... }\" section "
312 "when cache.mode = \"stateful\"");
313 goto error;
314 }
315
316 if (conf->tls_min_version >= (float)1.3) {
317 cf_log_err(ci, "cache.mode = \"stateful\" is not supported with tls_min_version >= 1.3");
318 goto error;
319 }
320 break;
321
322 case FR_TLS_CACHE_AUTO:
323 if (!conf->virtual_server) {
324 WARN("A virtual_server must be provided for stateful caching. "
325 "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
326 cache_stateless:
327 cache_mode = FR_TLS_CACHE_STATELESS;
328 break;
329 }
330
331 if (!cf_section_find(conf->virtual_server, "load", "session")) {
332 cf_log_warn(ci, "Specified virtual_server missing \"load session { ... }\" section. "
333 "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
334 goto cache_stateless;
335 }
336
337 if (!cf_section_find(conf->virtual_server, "store", "session")) {
338 cf_log_warn(ci, "Specified virtual_server missing \"store session { ... }\" section. "
339 "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
340 goto cache_stateless;
341 }
342
343 if (!cf_section_find(conf->virtual_server, "clear", "session")) {
344 cf_log_warn(ci, "Specified virtual_server missing \"clear cache { ... }\" section. "
345 "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
346 goto cache_stateless;
347 }
348
349 if (conf->tls_min_version >= (float)1.3) {
350 cf_log_err(ci, "stateful session-resumption is not supported with tls_min_version >= 1.3. "
351 "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\"");
352 goto cache_stateless;
353 }
354 break;
355 }
356
357 /*
358 * Generate random, ephemeral, session-ticket keys.
359 */
360 if (cache_mode & FR_TLS_CACHE_STATELESS) {
361 /*
362 * Fill the key with randomness if one
363 * wasn't specified by the user.
364 */
365 if (!conf->cache.session_ticket_key) {
366 MEM(conf->cache.session_ticket_key = talloc_array(conf, uint8_t, 256));
367 fr_rand_buffer(UNCONST(uint8_t *, conf->cache.session_ticket_key),
368 talloc_array_length(conf->cache.session_ticket_key));
369 }
370 }
371
372 *((int *)out) = cache_mode;
373
374 return 0;
375}
376
377#ifdef __APPLE__
378/*
379 * We don't want to put the private key password in eap.conf, so check
380 * for our special string which indicates we should get the password
381 * programmatically.
382 */
383static char const *special_string = "Apple:UsecertAdmin";
384
385/** Use cert_admin to retrieve the password for the private key
386 *
387 */
388static int conf_cert_admin_password(fr_tls_conf_t *conf)
389{
390 size_t i, cnt;
391
392 if (!conf->chains) return 0;
393
394 cnt = talloc_array_length(conf->chains);
395 for (i = 0; i < cnt; i++) {
396 char cmd[256];
397 char *password, *buf;
398 long const max_password_len = 128;
399 FILE *cmd_pipe;
400
401 if (!conf->chains[i]->password) continue;
402
403 if (strncmp(conf->chains[i]->password, special_string, strlen(special_string)) != 0) continue;
404
405 snprintf(cmd, sizeof(cmd) - 1, "/usr/sbin/certadmin --get-private-key-passphrase \"%s\"",
406 conf->chains[i]->private_key_file);
407
408 DEBUG2("Getting private key passphrase using command \"%s\"", cmd);
409
410 cmd_pipe = popen(cmd, "r");
411 if (!cmd_pipe) {
412 ERROR("%s command failed: Unable to get private_key_password", cmd);
413 ERROR("Error reading private_key_file %s", conf->chains[i]->private_key_file);
414 return -1;
415 }
416
417 password = talloc_array(conf, char, max_password_len);
418 if (!password) {
419 ERROR("Can't allocate space for private_key_password");
420 ERROR("Error reading private_key_file %s", conf->chains[i]->private_key_file);
421 pclose(cmd_pipe);
422 return -1;
423 }
424
425 buf = fgets(password, max_password_len, cmd_pipe);
426
427 if (!buf || ferror(cmd_pipe)) {
428 pclose(cmd_pipe);
429 talloc_free(password);
430 ERROR("%s command failed: Unable to get private_key_password", cmd);
431 ERROR("Error reading private_key_file %s", conf->chains[i]->private_key_file);
432 return -1;
433 }
434 pclose(cmd_pipe);
435
436 /* Get rid of newline at end of password. */
437 for (buf = password; buf < (password + max_password_len); buf++) {
438 if (*buf < ' ') {
439 *buf = '\0';
440 goto found;
441 }
442 }
443
444 talloc_free(password);
445 ERROR("%s command failed: Unable to get private_key_password", cmd);
446 ERROR("Error reading private_key_file %s - password is too long", conf->chains[i]->private_key_file);
447 return -1;
448
449 found:
450 DEBUG3("Password from command = \"%s\"", password);
451 talloc_const_free(conf->chains[i]->password);
452 conf->chains[i]->password = password;
453 }
454
455 return 0;
456}
457#endif
458
459#ifdef HAVE_OPENSSL_OCSP_H
460/*
461 * Create Global X509 revocation store and use it to verify
462 * OCSP responses
463 *
464 * - Load the trusted CAs
465 * - Load the trusted issuer certificates
466 */
467static X509_STORE *conf_ocsp_revocation_store(fr_tls_conf_t *conf)
468{
469 X509_STORE *store = NULL;
470
471 store = X509_STORE_new();
472
473 /* Load the CAs we trust */
474 if (conf->ca_file || conf->ca_path)
475 if (!X509_STORE_load_locations(store, conf->ca_file, conf->ca_path)) {
476 fr_tls_log(NULL, "Error reading Trusted root CA list \"%s\"", conf->ca_file);
477 X509_STORE_free(store);
478 return NULL;
479 }
480
481#ifdef X509_V_FLAG_CRL_CHECK_ALL
482 if (conf->verify.check_crl) X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
483#endif
484
485 return store;
486}
487#endif
488
489/*
490 * Free TLS client/server config
491 * Should not be called outside this code, as a callback is
492 * added to automatically free the data when the CONF_SECTION
493 * is freed.
494 */
495static int _conf_server_free(fr_tls_conf_t *conf)
496{
497 memset(conf, 0, sizeof(*conf));
498 return 0;
499}
500
501fr_tls_conf_t *fr_tls_conf_alloc(TALLOC_CTX *ctx)
502{
503 fr_tls_conf_t *conf;
504
505 MEM(conf = talloc_zero(ctx, fr_tls_conf_t));
506 talloc_set_destructor(conf, _conf_server_free);
507
508 return conf;
509}
510
511fr_tls_conf_t *fr_tls_conf_parse_server(CONF_SECTION *cs)
512{
513 fr_tls_conf_t *conf;
514
515 /*
516 * If cs has already been parsed there should be a cached copy
517 * of conf already stored, so just return that.
518 */
519 conf = cf_data_value(cf_data_find(cs, fr_tls_conf_t, NULL));
520 if (conf) {
521 DEBUG("Using cached TLS configuration from previous invocation");
522 return conf;
523 }
524
525 if (cf_section_rules_push(cs, fr_tls_server_config) < 0) return NULL;
526
527 conf = fr_tls_conf_alloc(cs);
528
529 if ((cf_section_parse(conf, conf, cs) < 0) ||
530 (cf_section_parse_pass2(conf, cs) < 0)) {
531#ifdef __APPLE__
532 error:
533#endif
535 return NULL;
536 }
537
538 /*
539 * Save people from their own stupidity.
540 */
541 if (conf->fragment_size < 100) conf->fragment_size = 100;
542
543 FR_INTEGER_BOUND_CHECK("padding", conf->padding_block_size, <=, SSL3_RT_MAX_PLAIN_LENGTH);
544
545#ifdef __APPLE__
546 if (conf_cert_admin_password(conf) < 0) goto error;
547#endif
548
549 /*
550 * Cache conf in cs in case we're asked to parse this again.
551 */
552 cf_data_add(cs, conf, NULL, false);
553
554 return conf;
555}
556
557fr_tls_conf_t *fr_tls_conf_parse_client(CONF_SECTION *cs)
558{
559 fr_tls_conf_t *conf;
560
561 conf = cf_data_value(cf_data_find(cs, fr_tls_conf_t, NULL));
562 if (conf) {
563 DEBUG2("Using cached TLS configuration from previous invocation");
564 return conf;
565 }
566
567 if (cf_section_rules_push(cs, fr_tls_client_config) < 0) return NULL;
568
569 conf = fr_tls_conf_alloc(cs);
570
571 if ((cf_section_parse(conf, conf, cs) < 0) ||
572 (cf_section_parse_pass2(conf, cs) < 0)) {
573#ifdef __APPLE__
574 error:
575#endif
577 return NULL;
578 }
579
580 /*
581 * Save people from their own stupidity.
582 */
583 if (conf->fragment_size < 100) conf->fragment_size = 100;
584
585 /*
586 * Initialize TLS
587 */
588#ifdef __APPLE__
589 if (conf_cert_admin_password(conf) < 0) goto error;
590#endif
591
592 cf_data_add(cs, conf, NULL, false);
593
594 return conf;
595}
596#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:1279
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:1707
int cf_section_parse_pass2(void *base, CONF_SECTION *cs)
Fixup xlat expansions and attributes.
Definition cf_parse.c:1389
#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.