22 #include "stir_shaken.h"
24 #define CONFIG_TYPE "verification"
26 #define DEFAULT_global_disable 0
28 #define DEFAULT_ca_file NULL
29 #define DEFAULT_ca_path NULL
30 #define DEFAULT_crl_file NULL
31 #define DEFAULT_crl_path NULL
32 static char DEFAULT_cert_cache_dir[PATH_MAX];
34 #define DEFAULT_curl_timeout 2
35 #define DEFAULT_max_iat_age 15
36 #define DEFAULT_max_date_header_age 15
37 #define DEFAULT_max_cache_entry_age 3600
38 #define DEFAULT_max_cache_size 1000
39 #define DEFAULT_stir_shaken_failure_action stir_shaken_failure_action_CONTINUE
40 #define DEFAULT_use_rfc9410_responses use_rfc9410_responses_NO
41 #define DEFAULT_relax_x5u_port_scheme_restrictions relax_x5u_port_scheme_restrictions_NO
42 #define DEFAULT_relax_x5u_path_restrictions relax_x5u_path_restrictions_NO
43 #define DEFAULT_load_system_certs load_system_certs_NO
47 #define STIR_SHAKEN_DIR_NAME "stir_shaken"
52 CONFIG_TYPE, CONFIG_TYPE);
57 return empty_cfg ?
ao2_bump(empty_cfg) : NULL;
60 int vs_is_config_loaded(
void)
63 CONFIG_TYPE, CONFIG_TYPE);
77 if (vcfg_common->tcs) {
78 crypto_free_cert_store(vcfg_common->tcs);
83 static void verification_destructor(
void *obj)
87 vcfg_cleanup(&cfg->vcfg_common);
90 static void *verification_alloc(
const char *name)
123 if (!cfg_dst || !cfg_src) {
127 if (!cfg_dst->tcs && cfg_src->tcs) {
128 cfg_sf_copy_wrapper(
id, cfg_dst, cfg_src, ca_file);
129 cfg_sf_copy_wrapper(
id, cfg_dst, cfg_src, ca_path);
130 cfg_sf_copy_wrapper(
id, cfg_dst, cfg_src, crl_file);
131 cfg_sf_copy_wrapper(
id, cfg_dst, cfg_src, crl_path);
133 cfg_dst->tcs = cfg_src->tcs;
136 cfg_sf_copy_wrapper(
id, cfg_dst, cfg_src, cert_cache_dir);
138 cfg_uint_copy(cfg_dst, cfg_src, curl_timeout);
139 cfg_uint_copy(cfg_dst, cfg_src, max_iat_age);
140 cfg_uint_copy(cfg_dst, cfg_src, max_date_header_age);
141 cfg_uint_copy(cfg_dst, cfg_src, max_cache_entry_age);
142 cfg_uint_copy(cfg_dst, cfg_src, max_cache_size);
144 cfg_enum_copy(cfg_dst, cfg_src, stir_shaken_failure_action);
145 cfg_enum_copy(cfg_dst, cfg_src, use_rfc9410_responses);
146 cfg_enum_copy(cfg_dst, cfg_src, relax_x5u_port_scheme_restrictions);
147 cfg_enum_copy(cfg_dst, cfg_src, relax_x5u_path_restrictions);
148 cfg_enum_copy(cfg_dst, cfg_src, load_system_certs);
158 int vs_check_common_config(
const char *
id,
161 SCOPE_ENTER(3,
"%s: Checking common config\n",
id);
163 if (!ast_strlen_zero(vcfg_common->ca_file)
165 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
166 "%s: ca_file '%s' not found, or is unreadable\n",
167 id, vcfg_common->ca_file);
170 if (!ast_strlen_zero(vcfg_common->ca_path)
172 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
173 "%s: ca_path '%s' not found, or is unreadable\n",
174 id, vcfg_common->ca_path);
177 if (!ast_strlen_zero(vcfg_common->crl_file)
179 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
180 "%s: crl_file '%s' not found, or is unreadable\n",
181 id, vcfg_common->crl_file);
184 if (!ast_strlen_zero(vcfg_common->crl_path)
186 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
187 "%s: crl_path '%s' not found, or is unreadable\n",
188 id, vcfg_common->crl_path);
191 if (!ast_strlen_zero(vcfg_common->ca_file)
192 || !ast_strlen_zero(vcfg_common->ca_path)) {
195 if (!vcfg_common->tcs) {
196 vcfg_common->tcs = crypto_create_cert_store();
197 if (!vcfg_common->tcs) {
198 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
199 "%s: Unable to create CA cert store\n",
id);
202 rc = crypto_load_cert_store(vcfg_common->tcs,
203 vcfg_common->ca_file, vcfg_common->ca_path);
205 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
206 "%s: Unable to load CA cert store from '%s' or '%s'\n",
207 id, vcfg_common->ca_file, vcfg_common->ca_path);
211 if (!ast_strlen_zero(vcfg_common->crl_file)
212 || !ast_strlen_zero(vcfg_common->crl_path)) {
215 if (!vcfg_common->tcs) {
216 vcfg_common->tcs = crypto_create_cert_store();
217 if (!vcfg_common->tcs) {
218 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
219 "%s: Unable to create CA cert store\n",
id);
222 rc = crypto_load_cert_store(vcfg_common->tcs,
223 vcfg_common->crl_file, vcfg_common->crl_path);
225 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
226 "%s: Unable to load CA CRL store from '%s' or '%s'\n",
227 id, vcfg_common->crl_file, vcfg_common->crl_path);
231 if (vcfg_common->tcs) {
232 if (ENUM_BOOL(vcfg_common->load_system_certs, load_system_certs)) {
233 X509_STORE_set_default_paths(vcfg_common->tcs->store);
236 if (!ast_strlen_zero(vcfg_common->crl_file)
237 || !ast_strlen_zero(vcfg_common->crl_path)) {
238 X509_STORE_set_flags(vcfg_common->tcs->store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
242 if (!ast_strlen_zero(vcfg_common->cert_cache_dir)) {
246 if (
ast_asprintf(&testfile,
"%s/testfile", vcfg_common->cert_cache_dir) <= 0) {
247 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
248 "%s: Unable to allocate memory for testfile\n",
id);
251 fp = fopen(testfile,
"w+");
254 SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR,
255 "%s: cert_cache_dir '%s' was not writable\n",
256 id, vcfg_common->cert_cache_dir);
263 SCOPE_EXIT_RTN_VALUE(0,
"%s: Done\n",
id);
266 static char *special_addresses[] = {
281 "255.255.255.255/32",
297 static int verification_apply(
const struct ast_sorcery *sorcery,
void *obj)
302 if (vs_check_common_config(
"verification", &cfg->vcfg_common) !=0) {
306 if (!cfg->vcfg_common.acl) {
311 ast_append_acl(
"permit",
"0.0.0.0/0", &cfg->vcfg_common.acl, &error, &ignore);
314 cfg->vcfg_common.acl = NULL;
315 ast_log(LOG_ERROR,
"%s: Unable to create default acl rule for '%s: %s'\n",
316 id,
"permit",
"0.0.0.0/0");
320 for (i = 0; i < ARRAY_LEN(special_addresses); i++) {
321 ast_append_acl(
"deny", special_addresses[i], &cfg->vcfg_common.acl, &error, &ignore);
324 cfg->vcfg_common.acl = NULL;
325 ast_log(LOG_ERROR,
"%s: Unable to create default acl rule for '%s: %s'\n",
326 id,
"deny", special_addresses[i]);
339 .title =
"Default Verification",
340 .object_type = config_object_type_verification,
345 e->
command =
"stir_shaken show verification";
347 "Usage: stir_shaken show verification\n"
348 " Show the stir/shaken verification settings\n";
355 return CLI_SHOWUSAGE;
359 config_object_cli_show(cfg, a, &data, 0);
367 AST_CLI_DEFINE(cli_verification_show,
"Show stir/shaken verification configuration"),
370 int vs_config_reload(
void)
375 if (!vs_is_config_loaded()) {
376 ast_log(LOG_WARNING,
"Stir/Shaken verification service disabled. Either there were errors in the 'verification' object in stir_shaken.conf or it was missing altogether.\n");
379 empty_cfg = verification_alloc(CONFIG_TYPE);
383 empty_cfg->global_disable = 1;
389 int vs_config_unload(
void)
392 ARRAY_LEN(verification_cli));
393 ao2_cleanup(empty_cfg);
398 int vs_config_load(
void)
402 snprintf(DEFAULT_cert_cache_dir,
sizeof(DEFAULT_cert_cache_dir),
"%s/keys/%s/cache",
403 ast_config_AST_DATA_DIR, STIR_SHAKEN_DIR_NAME);
405 ast_sorcery_apply_default(sorcery, CONFIG_TYPE,
"config",
406 "stir_shaken.conf,criteria=type=" CONFIG_TYPE
",single_object=yes,explicit_name=" CONFIG_TYPE);
409 NULL, verification_apply)) {
410 ast_log(LOG_ERROR,
"stir/shaken - failed to register '%s' sorcery object\n", CONFIG_TYPE);
418 DEFAULT_global_disable ?
"yes" :
"no",
421 register_common_verification_fields(sorcery,
verification_cfg, CONFIG_TYPE,);
425 if (!vs_is_config_loaded()) {
426 ast_log(LOG_WARNING,
"Stir/Shaken verification service disabled. Either there were errors in the 'verification' object in stir_shaken.conf or it was missing altogether.\n");
429 empty_cfg = verification_alloc(CONFIG_TYPE);
433 empty_cfg->global_disable = 1;
437 ARRAY_LEN(verification_cli));
#define ast_sorcery_object_field_register_nodoc(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object without documentation.
Asterisk main include file. File version handling, generic pbx functions.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
void ast_sorcery_force_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects even if no changes determin...
descriptor for a cli entry.
int ast_file_is_readable(const char *filename)
Test that a file exists and is readable by the effective user.
Full structure for sorcery.
Type for a default handler that should do nothing.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to load persistent objects.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Type for default option handler for bools (ast_true/ast_false)
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
struct ast_acl_list * ast_duplicate_acl_list(struct ast_acl_list *original)
Duplicates the contests of a list of lists of host access rules.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Verification Service configuration for stir/shaken.
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Standard Command Line Interface.
void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
Add a rule to an ACL struct.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object