From 679bcb687286fa72ed7dead3984d9eeb7252661e Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Mon, 2 Mar 2020 22:33:07 -0600 Subject: [PATCH] hx509: Add hx509.conf support Just like krb5.conf, but hx509.conf, with all the same default locations on Windows, OS X, and elsewhere, and HX509_CONFIG as the environment variable equivalent of KRB5_CONFIG. --- lib/base/context.c | 8 +++-- lib/hx509/cert.c | 76 ++++++++++++++++++++++++++++++++++++--------- lib/hx509/hx_locl.h | 2 ++ lib/krb5/context.c | 9 ++++-- 4 files changed, 75 insertions(+), 20 deletions(-) diff --git a/lib/base/context.c b/lib/base/context.c index 8bf0c1495..c116c6269 100644 --- a/lib/base/context.c +++ b/lib/base/context.c @@ -406,7 +406,7 @@ heim_error_code heim_set_config_files(heim_context context, char **filenames, heim_config_binding **res) { - heim_error_code ret; + heim_error_code ret = 0; *res = NULL; while (filenames != NULL && *filenames != NULL && **filenames != '\0') { @@ -421,10 +421,14 @@ heim_set_config_files(heim_context context, char **filenames, } #ifdef _WIN32 + /* + * We always ignored errors from loading from the registry, so we still do. + */ heim_load_config_from_registry(context, REGPATH_KERBEROS, REGPATH_HEIMDAL, res); + #endif - return ret; + return 0; } void diff --git a/lib/hx509/cert.c b/lib/hx509/cert.c index 598549cea..ff64b1d3f 100644 --- a/lib/hx509/cert.c +++ b/lib/hx509/cert.c @@ -125,6 +125,18 @@ hx509_get_instance(const char *libname) return 0; } +#define PATH_SEP ":" +static const char *hx509_config_file = +"~/.hx509/config" PATH_SEP +SYSCONFDIR "/hx509.conf" PATH_SEP +#ifdef _WIN32 +"%{COMMON_APPDATA}/Heimdal/hx509.conf" PATH_SEP +"%{WINDOWS}/hx509.ini" +#else /* _WIN32 */ +"/etc/hx509.conf" +#endif /* _WIN32 */ +; + /** * Creates a hx509 context that most functions in the library * uses. The context is only allowed to be used by one thread at each @@ -138,34 +150,68 @@ hx509_get_instance(const char *libname) */ HX509_LIB_FUNCTION int HX509_LIB_CALL -hx509_context_init(hx509_context *context) +hx509_context_init(hx509_context *contextp) { static heim_base_once_t init_context = HEIM_BASE_ONCE_INIT; + heim_error_code ret; + hx509_context context; + const char *anchors; + char **files = NULL; - *context = calloc(1, sizeof(**context)); - if (*context == NULL) + *contextp = NULL; + context = calloc(1, sizeof(*context)); + if (context == NULL) return ENOMEM; heim_base_once_f(&init_context, NULL, init_context_once); - _hx509_ks_null_register(*context); - _hx509_ks_mem_register(*context); - _hx509_ks_file_register(*context); - _hx509_ks_pkcs12_register(*context); - _hx509_ks_pkcs11_register(*context); - _hx509_ks_dir_register(*context); - _hx509_ks_keychain_register(*context); + if ((context->hcontext = heim_context_init()) == NULL) { + free(context); + return ENOMEM; + } - (*context)->ocsp_time_diff = HX509_DEFAULT_OCSP_TIME_DIFF; + if ((ret = heim_get_default_config_files(hx509_config_file, + "HX509_CONFIG", + &files))) { + heim_context_free(&context->hcontext); + free(context); + return ret; + } - initialize_hx_error_table_r(&(*context)->et_list); - initialize_asn1_error_table_r(&(*context)->et_list); + /* If there's no hx509 config, we continue, as we never needed it before */ + if (files) + (void) heim_set_config_files(context->hcontext, files, &context->cf); + heim_free_config_files(files); + + _hx509_ks_null_register(context); + _hx509_ks_mem_register(context); + _hx509_ks_file_register(context); + _hx509_ks_pkcs12_register(context); + _hx509_ks_pkcs11_register(context); + _hx509_ks_dir_register(context); + _hx509_ks_keychain_register(context); + + context->ocsp_time_diff = + heim_config_get_time_default(context->hcontext, context->cf, + HX509_DEFAULT_OCSP_TIME_DIFF, + "libdefaults", "ocsp_time_dif", NULL); + + initialize_hx_error_table_r(&context->et_list); + initialize_asn1_error_table_r(&context->et_list); #ifdef HX509_DEFAULT_ANCHORS - (void)hx509_certs_init(*context, HX509_DEFAULT_ANCHORS, 0, - NULL, &(*context)->default_trust_anchors); + anchors = heim_config_get_string_default(context->hcontext, context->cf, + HX509_DEFAULT_ANCHORS, + "libdefaults", "anchors", NULL); +#else + anchors = heim_config_get_string(context->hcontext, context->cf, + "libdefaults", "anchors", NULL); #endif + if (anchors) + (void)hx509_certs_init(context, anchors, 0, NULL, + &context->default_trust_anchors); + *contextp = context; return 0; } diff --git a/lib/hx509/hx_locl.h b/lib/hx509/hx_locl.h index 8603cb3ed..5d5c3bf3d 100644 --- a/lib/hx509/hx_locl.h +++ b/lib/hx509/hx_locl.h @@ -208,6 +208,8 @@ struct hx509_context_data { struct et_list *et_list; char *querystat; hx509_certs default_trust_anchors; + heim_context hcontext; + heim_config_section *cf; }; /* _hx509_calculate_path flag field */ diff --git a/lib/krb5/context.c b/lib/krb5/context.c index 4ca90a8cb..43c5d79fc 100644 --- a/lib/krb5/context.c +++ b/lib/krb5/context.c @@ -728,11 +728,14 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_set_config_files(krb5_context context, char **filenames) { krb5_error_code ret; + heim_config_binding *tmp = NULL; if ((ret = heim_set_config_files(context->hcontext, filenames, - &context->cf)) == 0) - ret = init_context_from_config_file(context); - return ret; + &tmp))) + return ret; + krb5_config_file_free(context, context->cf); + context->cf = tmp; + return init_context_from_config_file(context); } #ifndef HEIMDAL_SMALLER