Asterisk - The Open Source Telephony Project  18.5.0
general.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2020, Sangoma Technologies Corporation
5  *
6  * Kevin Harwell <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 #include "asterisk.h"
20 
21 #include "asterisk/cli.h"
22 #include "asterisk/sorcery.h"
23 
24 #include "stir_shaken.h"
25 #include "general.h"
27 
28 #define CONFIG_TYPE "general"
29 
30 #define DEFAULT_CA_FILE ""
31 #define DEFAULT_CA_PATH ""
32 #define DEFAULT_CACHE_MAX_SIZE 1000
33 #define DEFAULT_CURL_TIMEOUT 2
34 #define DEFAULT_SIGNATURE_TIMEOUT 15
35 
37  SORCERY_OBJECT(details);
39  /*! File path to a certificate authority */
41  /*! File path to a chain of trust */
43  );
44  /*! Maximum size of public keys cache */
45  unsigned int cache_max_size;
46  /*! Maximum time to wait to CURL certificates */
47  unsigned int curl_timeout;
48  /*! Amount of time a signature is valid for */
49  unsigned int signature_timeout;
50 };
51 
53 
55 {
56  struct stir_shaken_general *cfg;
57  struct ao2_container *container;
58 
61  if (!container || ao2_container_count(container) == 0) {
62  ao2_cleanup(container);
63  return ao2_bump(default_config);
64  }
65 
66  cfg = ao2_find(container, NULL, 0);
67  ao2_ref(container, -1);
68 
69  return cfg;
70 }
71 
72 const char *ast_stir_shaken_ca_file(const struct stir_shaken_general *cfg)
73 {
74  return cfg ? cfg->ca_file : DEFAULT_CA_FILE;
75 }
76 
77 const char *ast_stir_shaken_ca_path(const struct stir_shaken_general *cfg)
78 {
79  return cfg ? cfg->ca_path : DEFAULT_CA_PATH;
80 }
81 
82 unsigned int ast_stir_shaken_cache_max_size(const struct stir_shaken_general *cfg)
83 {
84  return cfg ? cfg->cache_max_size : DEFAULT_CACHE_MAX_SIZE;
85 }
86 
87 unsigned int ast_stir_shaken_curl_timeout(const struct stir_shaken_general *cfg)
88 {
89  return cfg ? cfg->curl_timeout : DEFAULT_CURL_TIMEOUT;
90 }
91 
93 {
94  return cfg ? cfg->signature_timeout : DEFAULT_SIGNATURE_TIMEOUT;
95 }
96 
97 static void stir_shaken_general_destructor(void *obj)
98 {
99  struct stir_shaken_general *cfg = obj;
100 
102 }
103 
104 static void *stir_shaken_general_alloc(const char *name)
105 {
106  struct stir_shaken_general *cfg;
107 
109  if (!cfg) {
110  return NULL;
111  }
112 
113  if (ast_string_field_init(cfg, 512)) {
114  ao2_ref(cfg, -1);
115  return NULL;
116  }
117 
118  return cfg;
119 }
120 
121 static int stir_shaken_general_apply(const struct ast_sorcery *sorcery, void *obj)
122 {
123  return 0;
124 }
125 
126 static void stir_shaken_general_loaded(const char *name, const struct ast_sorcery *sorcery,
127  const char *object_type, int reloaded)
128 {
129  struct stir_shaken_general *cfg;
130 
131  if (strcmp(object_type, CONFIG_TYPE)) {
132  /* Not interested */
133  return;
134  }
135 
136  if (default_config) {
137  ao2_ref(default_config, -1);
138  default_config = NULL;
139  }
140 
141  cfg = stir_shaken_general_get();
142  if (cfg) {
143  ao2_ref(cfg, -1);
144  return;
145  }
146 
147  /* Use the default configuration if on is not specified */
148  default_config = ast_sorcery_alloc(sorcery, CONFIG_TYPE, NULL);
149  if (default_config) {
150  stir_shaken_general_apply(sorcery, default_config);
151  }
152 }
153 
156 };
157 
158 static char *stir_shaken_general_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
159 {
160  struct stir_shaken_general *cfg;
161 
162  switch(cmd) {
163  case CLI_INIT:
164  e->command = "stir_shaken show general";
165  e->usage =
166  "Usage: stir_shaken show general\n"
167  " Show the general stir/shaken settings\n";
168  return NULL;
169  case CLI_GENERATE:
170  return NULL;
171  }
172 
173  if (a->argc != 3) {
174  return CLI_SHOWUSAGE;
175  }
176 
177  cfg = stir_shaken_general_get();
178  stir_shaken_cli_show(cfg, a, 0);
179  ao2_cleanup(cfg);
180 
181  return CLI_SUCCESS;
182 }
183 
185  AST_CLI_DEFINE(stir_shaken_general_show, "Show stir/shaken general configuration"),
186 };
187 
188 static int on_load_ca_file(const struct aco_option *opt, struct ast_variable *var, void *obj)
189 {
190  struct stir_shaken_general *cfg = obj;
191 
192  if (!ast_file_is_readable(var->value)) {
193  ast_log(LOG_ERROR, "stir/shaken - %s '%s' not found, or is unreadable\n",
194  var->name, var->value);
195  return -1;
196  }
197 
198  return ast_string_field_set(cfg, ca_file, var->value);
199 }
200 
201 static int ca_file_to_str(const void *obj, const intptr_t *args, char **buf)
202 {
203  const struct stir_shaken_general *cfg = obj;
204 
205  *buf = ast_strdup(cfg->ca_file);
206 
207  return 0;
208 }
209 
210 static int on_load_ca_path(const struct aco_option *opt, struct ast_variable *var, void *obj)
211 {
212  struct stir_shaken_general *cfg = obj;
213 
214  if (!ast_file_is_readable(var->value)) {
215  ast_log(LOG_ERROR, "stir/shaken - %s '%s' not found, or is unreadable\n",
216  var->name, var->value);
217  return -1;
218  }
219 
220  return ast_string_field_set(cfg, ca_path, var->value);
221 }
222 
223 static int ca_path_to_str(const void *obj, const intptr_t *args, char **buf)
224 {
225  const struct stir_shaken_general *cfg = obj;
226 
227  *buf = ast_strdup(cfg->ca_path);
228 
229  return 0;
230 }
231 
233 {
234  ast_cli_unregister_multiple(stir_shaken_general_cli,
235  ARRAY_LEN(stir_shaken_general_cli));
236 
238  &stir_shaken_general_observer);
239 
240  if (default_config) {
241  ao2_ref(default_config, -1);
242  default_config = NULL;
243  }
244 
245  return 0;
246 }
247 
249 {
251 
252  ast_sorcery_apply_default(sorcery, CONFIG_TYPE, "config",
253  "stir_shaken.conf,criteria=type=general,single_object=yes,explicit_name=general");
254 
257  ast_log(LOG_ERROR, "stir/shaken - failed to register '%s' sorcery object\n", CONFIG_TYPE);
258  return -1;
259  }
260 
261  ast_sorcery_object_field_register(sorcery, CONFIG_TYPE, "type", "", OPT_NOOP_T, 0, 0);
266  ast_sorcery_object_field_register(sorcery, CONFIG_TYPE, "cache_max_size",
269  ast_sorcery_object_field_register(sorcery, CONFIG_TYPE, "curl_timeout",
272  ast_sorcery_object_field_register(sorcery, CONFIG_TYPE, "signature_timeout",
275 
276  if (ast_sorcery_instance_observer_add(sorcery, &stir_shaken_general_observer)) {
277  ast_log(LOG_ERROR, "stir/shaken - failed to register loaded observer for '%s' "
278  "sorcery object type\n", CONFIG_TYPE);
279  return -1;
280  }
281 
282  ast_cli_register_multiple(stir_shaken_general_cli,
283  ARRAY_LEN(stir_shaken_general_cli));
284 
285  return 0;
286 }
struct stir_shaken_general * stir_shaken_general_get()
Retrieve the stir/shaken &#39;general&#39; configuration object.
Definition: general.c:54
static int stir_shaken_general_apply(const struct ast_sorcery *sorcery, void *obj)
Definition: general.c:121
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
#define DEFAULT_CA_FILE
Definition: general.c:30
Asterisk main include file. File version handling, generic pbx functions.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
unsigned int signature_timeout
Definition: general.c:49
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
Definition: sorcery.c:520
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int stir_shaken_general_unload(void)
Unload time cleanup for the stir/shaken &#39;general&#39; configuration.
Definition: general.c:232
static int on_load_ca_file(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: general.c:188
descriptor for a cli entry.
Definition: cli.h:171
const int argc
Definition: cli.h:160
int ast_file_is_readable(const char *filename)
Test that a file exists and is readable by the effective user.
Definition: main/utils.c:2855
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
unsigned int ast_stir_shaken_cache_max_size(const struct stir_shaken_general *cfg)
Retrieve the &#39;cache_max_size&#39; general configuration option value.
Definition: general.c:82
static int ca_file_to_str(const void *obj, const intptr_t *args, char **buf)
Definition: general.c:201
Perform no matching, return all objects.
Definition: sorcery.h:123
Definition: cli.h:152
Full structure for sorcery.
Definition: sorcery.c:230
Type for a default handler that should do nothing.
static struct stir_shaken_general * default_config
Definition: general.c:52
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static struct ast_cli_entry stir_shaken_general_cli[]
Definition: general.c:184
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
Definition: stringfields.h:337
Return all matching objects.
Definition: sorcery.h:120
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * args
#define NULL
Definition: resample.c:96
static const struct ast_sorcery_instance_observer stir_shaken_general_observer
Definition: general.c:154
#define CONFIG_TYPE
Definition: general.c:28
unsigned int ast_stir_shaken_signature_timeout(const struct stir_shaken_general *cfg)
Retrieve the &#39;signature_timeout&#39; general configuration option value.
Definition: general.c:92
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
Definition: sorcery.h:1005
#define __stringify(x)
Definition: asterisk.h:214
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
static int on_load_ca_path(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: general.c:210
Type for default option handler for unsigned integers.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
unsigned int curl_timeout
Definition: general.c:47
Interface for the sorcery instance observer.
Definition: sorcery.h:237
#define AST_STRING_FIELD(name)
Declare a string field.
Definition: stringfields.h:299
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * container
Definition: res_fax.c:502
#define DEFAULT_SIGNATURE_TIMEOUT
Definition: general.c:34
int stir_shaken_cli_show(void *obj, void *arg, int flags)
Output configuration settings to the Asterisk CLI.
Definition: stir_shaken.c:35
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition: sorcery.h:838
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
Definition: sorcery.c:537
#define DEFAULT_CA_PATH
Definition: general.c:31
#define LOG_ERROR
Definition: logger.h:285
#define CLI_SHOWUSAGE
Definition: cli.h:45
const char * ast_stir_shaken_ca_file(const struct stir_shaken_general *cfg)
Retrieve the &#39;ca_file&#39; general configuration option value.
Definition: general.c:72
#define ast_sorcery_apply_default(sorcery, type, name, data)
Definition: sorcery.h:477
static int ca_path_to_str(const void *obj, const intptr_t *args, char **buf)
Definition: general.c:223
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
static void * stir_shaken_general_alloc(const char *name)
Definition: general.c:104
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
#define DEFAULT_CURL_TIMEOUT
Definition: general.c:33
struct ast_sorcery * ast_stir_shaken_sorcery(void)
Retrieve the stir/shaken sorcery context.
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static void stir_shaken_general_destructor(void *obj)
Definition: general.c:97
#define DEFAULT_CACHE_MAX_SIZE
Definition: general.c:32
const char * usage
Definition: cli.h:177
static void stir_shaken_general_loaded(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
Definition: general.c:126
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition: sorcery.h:955
#define CLI_SUCCESS
Definition: cli.h:44
void(* object_type_loaded)(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
Callback after any object_type is loaded/reloaded.
Definition: sorcery.h:260
const ast_string_field ca_file
Definition: general.c:43
const char * ast_stir_shaken_ca_path(const struct stir_shaken_general *cfg)
Retrieve the &#39;ca_path&#39; general configuration option value.
Definition: general.c:77
static struct ast_sorcery * sorcery
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Standard Command Line Interface.
const ast_string_field ca_path
Definition: general.c:43
Generic container type.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728
int stir_shaken_general_load(void)
Load time initialization for the stir/shaken &#39;general&#39; configuration.
Definition: general.c:248
static char * stir_shaken_general_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: general.c:158
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368
Sorcery Data Access Layer API.
unsigned int cache_max_size
Definition: general.c:45
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
static struct test_val a
unsigned int ast_stir_shaken_curl_timeout(const struct stir_shaken_general *cfg)
Retrieve the &#39;curl_timeout&#39; general configuration option value.
Definition: general.c:87