]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/conf/conf_mod.c
Make rcu_thread_key context-aware
[thirdparty/openssl.git] / crypto / conf / conf_mod.c
CommitLineData
0f113f3e 1/*
b6461792 2 * Copyright 2002-2024 The OpenSSL Project Authors. All Rights Reserved.
bc37d996 3 *
2044d382 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
62867571
RS
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
bc37d996
DSH
8 */
9
e4468e6d
P
10/* We need to use some engine deprecated APIs */
11#define OPENSSL_SUPPRESS_DEPRECATED
12
07016a8a 13#include "internal/cryptlib.h"
504e72fc 14#include "internal/rcu.h"
bc37d996 15#include <stdio.h>
df5eaa8a 16#include <ctype.h>
bc37d996 17#include <openssl/crypto.h>
cbf6959f 18#include "internal/conf.h"
6229815a 19#include <openssl/conf_api.h>
921de151 20#include "internal/dso.h"
22e27978 21#include "internal/thread_once.h"
bc37d996 22#include <openssl/x509.h>
0196ad63 23#include <openssl/trace.h>
22e27978 24#include <openssl/engine.h>
ff234c68 25#include "conf_local.h"
bc37d996 26
852c2ed2
RS
27DEFINE_STACK_OF(CONF_MODULE)
28DEFINE_STACK_OF(CONF_IMODULE)
29
bc37d996
DSH
30#define DSO_mod_init_name "OPENSSL_init"
31#define DSO_mod_finish_name "OPENSSL_finish"
32
0f113f3e
MC
33/*
34 * This structure contains a data about supported modules. entries in this
35 * table correspond to either dynamic or static modules.
bc37d996
DSH
36 */
37
0f113f3e
MC
38struct conf_module_st {
39 /* DSO of this module or NULL if static */
40 DSO *dso;
41 /* Name of the module */
42 char *name;
43 /* Init function */
44 conf_init_func *init;
45 /* Finish function */
46 conf_finish_func *finish;
47 /* Number of successfully initialized modules */
48 int links;
49 void *usr_data;
50};
51
52/*
53 * This structure contains information about modules that have been
54 * successfully initialized. There may be more than one entry for a given
55 * module.
bc37d996
DSH
56 */
57
0f113f3e
MC
58struct conf_imodule_st {
59 CONF_MODULE *pmod;
60 char *name;
61 char *value;
62 unsigned long flags;
63 void *usr_data;
64};
bc37d996 65
ef7a9b44 66static CRYPTO_ONCE init_module_list_lock = CRYPTO_ONCE_STATIC_INIT;
504e72fc 67static CRYPTO_RCU_LOCK *module_list_lock = NULL;
ef7a9b44
HL
68static STACK_OF(CONF_MODULE) *supported_modules = NULL; /* protected by lock */
69static STACK_OF(CONF_IMODULE) *initialized_modules = NULL; /* protected by lock */
bc37d996 70
22e27978
SL
71static CRYPTO_ONCE load_builtin_modules = CRYPTO_ONCE_STATIC_INIT;
72
bc37d996
DSH
73static void module_free(CONF_MODULE *md);
74static void module_finish(CONF_IMODULE *imod);
159b9a4d 75static int module_run(const CONF *cnf, const char *name, const char *value,
0f113f3e 76 unsigned long flags);
cca28b29 77static CONF_MODULE *module_add(DSO *dso, const char *name,
0f113f3e
MC
78 conf_init_func *ifunc,
79 conf_finish_func *ffunc);
159b9a4d
F
80static CONF_MODULE *module_find(const char *name);
81static int module_init(CONF_MODULE *pmod, const char *name, const char *value,
0f113f3e 82 const CONF *cnf);
02e112a8 83static CONF_MODULE *module_load_dso(const CONF *cnf, const char *name,
159b9a4d 84 const char *value);
bc37d996 85
697d0b5b
MC
86static int conf_modules_finish_int(void);
87
ef7a9b44
HL
88static void module_lists_free(void)
89{
504e72fc 90 ossl_rcu_lock_free(module_list_lock);
ef7a9b44
HL
91 module_list_lock = NULL;
92
93 sk_CONF_MODULE_free(supported_modules);
94 supported_modules = NULL;
95
96 sk_CONF_IMODULE_free(initialized_modules);
97 initialized_modules = NULL;
98}
99
100DEFINE_RUN_ONCE_STATIC(do_init_module_list_lock)
101{
24d16d3a 102 module_list_lock = ossl_rcu_lock_new(1, NULL);
ef7a9b44 103 if (module_list_lock == NULL) {
e077455e 104 ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
ef7a9b44
HL
105 return 0;
106 }
107
108 return 1;
109}
110
33855c0a
P
111static int conf_diagnostics(const CONF *cnf)
112{
55c61473 113 return _CONF_get_number(cnf, NULL, "config_diagnostics") != 0;
33855c0a
P
114}
115
bc37d996
DSH
116/* Main function: load modules from a CONF structure */
117
9dd5ae65 118int CONF_modules_load(const CONF *cnf, const char *appname,
0f113f3e
MC
119 unsigned long flags)
120{
121 STACK_OF(CONF_VALUE) *values;
122 CONF_VALUE *vl;
123 char *vsection = NULL;
0f113f3e 124 int ret, i;
bc37d996 125
0f113f3e
MC
126 if (!cnf)
127 return 1;
bc37d996 128
33855c0a
P
129 if (conf_diagnostics(cnf))
130 flags &= ~(CONF_MFLAGS_IGNORE_ERRORS
131 | CONF_MFLAGS_IGNORE_RETURN_CODES
132 | CONF_MFLAGS_SILENT
133 | CONF_MFLAGS_IGNORE_MISSING_FILE);
134
55c61473 135 ERR_set_mark();
0f113f3e
MC
136 if (appname)
137 vsection = NCONF_get_string(cnf, NULL, appname);
bc37d996 138
0f113f3e
MC
139 if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
140 vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
bc37d996 141
0f113f3e 142 if (!vsection) {
55c61473 143 ERR_pop_to_mark();
0f113f3e
MC
144 return 1;
145 }
bc37d996 146
0196ad63 147 OSSL_TRACE1(CONF, "Configuration in section %s\n", vsection);
0f113f3e 148 values = NCONF_get_section(cnf, vsection);
bc37d996 149
33b4f731
P
150 if (values == NULL) {
151 if (!(flags & CONF_MFLAGS_SILENT)) {
55c61473 152 ERR_clear_last_mark();
a150f8e1
RL
153 ERR_raise_data(ERR_LIB_CONF,
154 CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION,
155 "openssl_conf=%s", vsection);
55c61473
DDO
156 } else {
157 ERR_pop_to_mark();
33b4f731 158 }
0f113f3e 159 return 0;
33b4f731 160 }
55c61473 161 ERR_pop_to_mark();
bc37d996 162
0f113f3e
MC
163 for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
164 vl = sk_CONF_VALUE_value(values, i);
55c61473 165 ERR_set_mark();
0f113f3e 166 ret = module_run(cnf, vl->name, vl->value, flags);
0196ad63
RL
167 OSSL_TRACE3(CONF, "Running module %s (%s) returned %d\n",
168 vl->name, vl->value, ret);
0f113f3e 169 if (ret <= 0)
55c61473
DDO
170 if (!(flags & CONF_MFLAGS_IGNORE_ERRORS)) {
171 ERR_clear_last_mark();
0f113f3e 172 return ret;
55c61473
DDO
173 }
174 ERR_pop_to_mark();
0f113f3e 175 }
bc37d996 176
0f113f3e 177 return 1;
bc37d996 178
0f113f3e 179}
bc37d996 180
b4250010 181int CONF_modules_load_file_ex(OSSL_LIB_CTX *libctx, const char *filename,
d8652be0 182 const char *appname, unsigned long flags)
0f113f3e
MC
183{
184 char *file = NULL;
185 CONF *conf = NULL;
33855c0a 186 int ret = 0, diagnostics = 0;
22e27978 187
8b7d5ea7
TM
188 ERR_set_mark();
189
0f113f3e
MC
190 if (filename == NULL) {
191 file = CONF_get1_default_config_file();
22e27978 192 if (file == NULL)
0f113f3e 193 goto err;
8b7d5ea7
TM
194 if (*file == '\0') {
195 /* Do not try to load an empty file name but do not error out */
196 ret = 1;
197 goto err;
198 }
22e27978 199 } else {
0f113f3e 200 file = (char *)filename;
22e27978 201 }
0f113f3e 202
15795943
DDO
203 conf = NCONF_new_ex(libctx, NULL);
204 if (conf == NULL)
205 goto err;
206
0f113f3e
MC
207 if (NCONF_load(conf, file, NULL) <= 0) {
208 if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
209 (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) {
0f113f3e
MC
210 ret = 1;
211 }
212 goto err;
213 }
214
215 ret = CONF_modules_load(conf, appname, flags);
33855c0a 216 diagnostics = conf_diagnostics(conf);
0f113f3e
MC
217
218 err:
219 if (filename == NULL)
220 OPENSSL_free(file);
221 NCONF_free(conf);
222
33855c0a 223 if ((flags & CONF_MFLAGS_IGNORE_RETURN_CODES) != 0 && !diagnostics)
55c61473 224 ret = 1;
df1f538f 225
b8ae4a83 226 if (ret > 0)
55c61473
DDO
227 ERR_pop_to_mark();
228 else
229 ERR_clear_last_mark();
b8ae4a83 230
0f113f3e
MC
231 return ret;
232}
bc37d996 233
22e27978
SL
234int CONF_modules_load_file(const char *filename,
235 const char *appname, unsigned long flags)
236{
d8652be0 237 return CONF_modules_load_file_ex(NULL, filename, appname, flags);
22e27978
SL
238}
239
240DEFINE_RUN_ONCE_STATIC(do_load_builtin_modules)
241{
242 OPENSSL_load_builtin_modules();
243#ifndef OPENSSL_NO_ENGINE
244 /* Need to load ENGINEs */
245 ENGINE_load_builtin_engines();
246#endif
22e27978
SL
247 return 1;
248}
249
159b9a4d 250static int module_run(const CONF *cnf, const char *name, const char *value,
0f113f3e
MC
251 unsigned long flags)
252{
253 CONF_MODULE *md;
254 int ret;
255
22e27978
SL
256 if (!RUN_ONCE(&load_builtin_modules, do_load_builtin_modules))
257 return -1;
258
0f113f3e
MC
259 md = module_find(name);
260
261 /* Module not found: try to load DSO */
262 if (!md && !(flags & CONF_MFLAGS_NO_DSO))
a773b52a 263 md = module_load_dso(cnf, name, value);
0f113f3e
MC
264
265 if (!md) {
266 if (!(flags & CONF_MFLAGS_SILENT)) {
a150f8e1
RL
267 ERR_raise_data(ERR_LIB_CONF, CONF_R_UNKNOWN_MODULE_NAME,
268 "module=%s", name);
0f113f3e
MC
269 }
270 return -1;
271 }
272
273 ret = module_init(md, name, value, cnf);
274
275 if (ret <= 0) {
a150f8e1
RL
276 if (!(flags & CONF_MFLAGS_SILENT))
277 ERR_raise_data(ERR_LIB_CONF, CONF_R_MODULE_INITIALIZATION_ERROR,
278 "module=%s, value=%s retcode=%-8d",
279 name, value, ret);
0f113f3e
MC
280 }
281
282 return ret;
283}
bc37d996
DSH
284
285/* Load a module from a DSO */
02e112a8 286static CONF_MODULE *module_load_dso(const CONF *cnf,
159b9a4d 287 const char *name, const char *value)
0f113f3e
MC
288{
289 DSO *dso = NULL;
290 conf_init_func *ifunc;
291 conf_finish_func *ffunc;
159b9a4d 292 const char *path = NULL;
0f113f3e
MC
293 int errcode = 0;
294 CONF_MODULE *md;
12a765a5 295
0f113f3e 296 /* Look for alternative path in module section */
55c61473 297 path = _CONF_get_string(cnf, value, "path");
12a765a5 298 if (path == NULL) {
0f113f3e
MC
299 path = name;
300 }
301 dso = DSO_load(NULL, path, NULL, 0);
12a765a5 302 if (dso == NULL) {
0f113f3e
MC
303 errcode = CONF_R_ERROR_LOADING_DSO;
304 goto err;
305 }
306 ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
12a765a5 307 if (ifunc == NULL) {
0f113f3e
MC
308 errcode = CONF_R_MISSING_INIT_FUNCTION;
309 goto err;
310 }
311 ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
312 /* All OK, add module */
313 md = module_add(dso, name, ifunc, ffunc);
314
12a765a5 315 if (md == NULL)
0f113f3e
MC
316 goto err;
317
318 return md;
319
320 err:
efa7dd64 321 DSO_free(dso);
a150f8e1 322 ERR_raise_data(ERR_LIB_CONF, errcode, "module=%s, path=%s", name, path);
0f113f3e
MC
323 return NULL;
324}
bc37d996
DSH
325
326/* add module to list */
cca28b29 327static CONF_MODULE *module_add(DSO *dso, const char *name,
0f113f3e
MC
328 conf_init_func *ifunc, conf_finish_func *ffunc)
329{
330 CONF_MODULE *tmod = NULL;
504e72fc
NH
331 STACK_OF(CONF_MODULE) *old_modules;
332 STACK_OF(CONF_MODULE) *new_modules;
ef7a9b44
HL
333
334 if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
335 return NULL;
336
504e72fc
NH
337 ossl_rcu_write_lock(module_list_lock);
338
339 old_modules = ossl_rcu_deref(&supported_modules);
340
341 if (old_modules == NULL)
342 new_modules = sk_CONF_MODULE_new_null();
343 else
344 new_modules = sk_CONF_MODULE_dup(old_modules);
ef7a9b44 345
504e72fc 346 if (new_modules == NULL)
ef7a9b44 347 goto err;
504e72fc 348
e077455e 349 if ((tmod = OPENSSL_zalloc(sizeof(*tmod))) == NULL)
ef7a9b44 350 goto err;
0f113f3e
MC
351
352 tmod->dso = dso;
7644a9ae 353 tmod->name = OPENSSL_strdup(name);
0f113f3e
MC
354 tmod->init = ifunc;
355 tmod->finish = ffunc;
ef7a9b44
HL
356 if (tmod->name == NULL)
357 goto err;
358
504e72fc 359 if (!sk_CONF_MODULE_push(new_modules, tmod))
ef7a9b44 360 goto err;
0f113f3e 361
504e72fc
NH
362 ossl_rcu_assign_ptr(&supported_modules, &new_modules);
363 ossl_rcu_write_unlock(module_list_lock);
364 ossl_synchronize_rcu(module_list_lock);
365
366 sk_CONF_MODULE_free(old_modules);
ef7a9b44
HL
367 return tmod;
368
369 err:
504e72fc 370 ossl_rcu_write_unlock(module_list_lock);
ef7a9b44 371 if (tmod != NULL) {
b7b8e948 372 OPENSSL_free(tmod->name);
0f113f3e 373 OPENSSL_free(tmod);
0f113f3e 374 }
707b54be 375 sk_CONF_MODULE_free(new_modules);
ef7a9b44 376 return NULL;
0f113f3e
MC
377}
378
379/*
380 * Find a module from the list. We allow module names of the form
381 * modname.XXXX to just search for modname to allow the same module to be
382 * initialized more than once.
bc37d996
DSH
383 */
384
159b9a4d 385static CONF_MODULE *module_find(const char *name)
0f113f3e
MC
386{
387 CONF_MODULE *tmod;
388 int i, nchar;
389 char *p;
504e72fc
NH
390 STACK_OF(CONF_MODULE) *mods;
391
0f113f3e 392 p = strrchr(name, '.');
bc37d996 393
0f113f3e
MC
394 if (p)
395 nchar = p - name;
396 else
397 nchar = strlen(name);
bc37d996 398
ef7a9b44
HL
399 if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
400 return NULL;
401
504e72fc
NH
402 ossl_rcu_read_lock(module_list_lock);
403 mods = ossl_rcu_deref(&supported_modules);
ef7a9b44 404
504e72fc
NH
405 for (i = 0; i < sk_CONF_MODULE_num(mods); i++) {
406 tmod = sk_CONF_MODULE_value(mods, i);
ef7a9b44 407 if (strncmp(tmod->name, name, nchar) == 0) {
504e72fc 408 ossl_rcu_read_unlock(module_list_lock);
0f113f3e 409 return tmod;
ef7a9b44 410 }
0f113f3e 411 }
bc37d996 412
504e72fc 413 ossl_rcu_read_unlock(module_list_lock);
0f113f3e 414 return NULL;
0f113f3e 415}
bc37d996
DSH
416
417/* initialize a module */
159b9a4d 418static int module_init(CONF_MODULE *pmod, const char *name, const char *value,
0f113f3e
MC
419 const CONF *cnf)
420{
421 int ret = 1;
422 int init_called = 0;
423 CONF_IMODULE *imod = NULL;
504e72fc
NH
424 STACK_OF(CONF_IMODULE) *old_modules;
425 STACK_OF(CONF_IMODULE) *new_modules;
0f113f3e
MC
426
427 /* Otherwise add initialized module to list */
b4faea50 428 imod = OPENSSL_malloc(sizeof(*imod));
90945fa3 429 if (imod == NULL)
0f113f3e
MC
430 goto err;
431
432 imod->pmod = pmod;
7644a9ae
RS
433 imod->name = OPENSSL_strdup(name);
434 imod->value = OPENSSL_strdup(value);
0f113f3e
MC
435 imod->usr_data = NULL;
436
437 if (!imod->name || !imod->value)
438 goto memerr;
439
440 /* Try to initialize module */
441 if (pmod->init) {
442 ret = pmod->init(imod, cnf);
443 init_called = 1;
444 /* Error occurred, exit */
445 if (ret <= 0)
446 goto err;
447 }
448
ef7a9b44
HL
449 if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
450 goto err;
451
504e72fc 452 ossl_rcu_write_lock(module_list_lock);
ef7a9b44 453
504e72fc
NH
454 old_modules = ossl_rcu_deref(&initialized_modules);
455
456 if (old_modules == NULL)
457 new_modules = sk_CONF_IMODULE_new_null();
458 else
459 new_modules = sk_CONF_IMODULE_dup(old_modules);
460
461 if (new_modules == NULL) {
462 ossl_rcu_write_unlock(module_list_lock);
463 ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
464 goto err;
0f113f3e
MC
465 }
466
504e72fc
NH
467 if (!sk_CONF_IMODULE_push(new_modules, imod)) {
468 ossl_rcu_write_unlock(module_list_lock);
e077455e 469 ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB);
0f113f3e
MC
470 goto err;
471 }
472
473 pmod->links++;
474
504e72fc
NH
475 ossl_rcu_assign_ptr(&initialized_modules, &new_modules);
476 ossl_rcu_write_unlock(module_list_lock);
477 ossl_synchronize_rcu(module_list_lock);
478 sk_CONF_IMODULE_free(old_modules);
0f113f3e
MC
479 return ret;
480
481 err:
482
483 /* We've started the module so we'd better finish it */
484 if (pmod->finish && init_called)
485 pmod->finish(imod);
486
487 memerr:
488 if (imod) {
b548a1f1
RS
489 OPENSSL_free(imod->name);
490 OPENSSL_free(imod->value);
0f113f3e
MC
491 OPENSSL_free(imod);
492 }
493
494 return -1;
495
496}
497
498/*
499 * Unload any dynamic modules that have a link count of zero: i.e. have no
500 * active initialized modules. If 'all' is set then all modules are unloaded
501 * including static ones.
bc37d996
DSH
502 */
503
504void CONF_modules_unload(int all)
0f113f3e
MC
505{
506 int i;
507 CONF_MODULE *md;
504e72fc
NH
508 STACK_OF(CONF_MODULE) *old_modules;
509 STACK_OF(CONF_MODULE) *new_modules;
510 STACK_OF(CONF_MODULE) *to_delete;
ef7a9b44 511
697d0b5b
MC
512 if (!conf_modules_finish_int()) /* also inits module list lock */
513 return;
ef7a9b44 514
504e72fc
NH
515 ossl_rcu_write_lock(module_list_lock);
516
517 old_modules = ossl_rcu_deref(&supported_modules);
518 new_modules = sk_CONF_MODULE_dup(old_modules);
519 to_delete = sk_CONF_MODULE_new_null();
520
521 if (new_modules == NULL) {
522 ossl_rcu_write_unlock(module_list_lock);
ef7a9b44 523 return;
504e72fc 524 }
ef7a9b44 525
0f113f3e 526 /* unload modules in reverse order */
504e72fc
NH
527 for (i = sk_CONF_MODULE_num(new_modules) - 1; i >= 0; i--) {
528 md = sk_CONF_MODULE_value(new_modules, i);
0f113f3e
MC
529 /* If static or in use and 'all' not set ignore it */
530 if (((md->links > 0) || !md->dso) && !all)
531 continue;
532 /* Since we're working in reverse this is OK */
504e72fc
NH
533 (void)sk_CONF_MODULE_delete(new_modules, i);
534 sk_CONF_MODULE_push(to_delete, md);
0f113f3e 535 }
ef7a9b44 536
504e72fc
NH
537 if (sk_CONF_MODULE_num(new_modules) == 0) {
538 sk_CONF_MODULE_free(new_modules);
539 new_modules = NULL;
0f113f3e 540 }
ef7a9b44 541
504e72fc
NH
542 ossl_rcu_assign_ptr(&supported_modules, &new_modules);
543 ossl_rcu_write_unlock(module_list_lock);
544 ossl_synchronize_rcu(module_list_lock);
545 sk_CONF_MODULE_free(old_modules);
546 sk_CONF_MODULE_pop_free(to_delete, module_free);
547
0f113f3e 548}
bc37d996
DSH
549
550/* unload a single module */
551static void module_free(CONF_MODULE *md)
0f113f3e 552{
efa7dd64 553 DSO_free(md->dso);
0f113f3e
MC
554 OPENSSL_free(md->name);
555 OPENSSL_free(md);
556}
bc37d996
DSH
557
558/* finish and free up all modules instances */
559
697d0b5b 560static int conf_modules_finish_int(void)
0f113f3e
MC
561{
562 CONF_IMODULE *imod;
504e72fc
NH
563 STACK_OF(CONF_IMODULE) *old_modules;
564 STACK_OF(CONF_IMODULE) *new_modules = NULL;
ef7a9b44
HL
565
566 if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
697d0b5b 567 return 0;
ef7a9b44 568
d840f07b 569 /* If module_list_lock is NULL here it means we were already unloaded */
504e72fc 570 if (module_list_lock == NULL)
697d0b5b 571 return 0;
ef7a9b44 572
504e72fc
NH
573 ossl_rcu_write_lock(module_list_lock);
574 old_modules = ossl_rcu_deref(&initialized_modules);
575 ossl_rcu_assign_ptr(&initialized_modules, &new_modules);
576 ossl_rcu_write_unlock(module_list_lock);
577 ossl_synchronize_rcu(module_list_lock);
578
579 while (sk_CONF_IMODULE_num(old_modules) > 0) {
580 imod = sk_CONF_IMODULE_pop(old_modules);
0f113f3e
MC
581 module_finish(imod);
582 }
504e72fc 583 sk_CONF_IMODULE_free(old_modules);
697d0b5b
MC
584
585 return 1;
586}
587
588void CONF_modules_finish(void)
589{
590 conf_modules_finish_int();
0f113f3e 591}
bc37d996
DSH
592
593/* finish a module instance */
594
595static void module_finish(CONF_IMODULE *imod)
0f113f3e 596{
efa7dd64
RS
597 if (!imod)
598 return;
0f113f3e
MC
599 if (imod->pmod->finish)
600 imod->pmod->finish(imod);
601 imod->pmod->links--;
602 OPENSSL_free(imod->name);
603 OPENSSL_free(imod->value);
604 OPENSSL_free(imod);
605}
bc37d996
DSH
606
607/* Add a static module to OpenSSL */
608
0f113f3e
MC
609int CONF_module_add(const char *name, conf_init_func *ifunc,
610 conf_finish_func *ffunc)
611{
612 if (module_add(NULL, name, ifunc, ffunc))
613 return 1;
614 else
615 return 0;
616}
bc37d996 617
f148f703 618void ossl_config_modules_free(void)
0f113f3e 619{
ef7a9b44
HL
620 CONF_modules_unload(1); /* calls CONF_modules_finish */
621 module_lists_free();
0f113f3e 622}
bc37d996
DSH
623
624/* Utility functions */
625
9dd5ae65 626const char *CONF_imodule_get_name(const CONF_IMODULE *md)
0f113f3e
MC
627{
628 return md->name;
629}
bc37d996 630
9dd5ae65 631const char *CONF_imodule_get_value(const CONF_IMODULE *md)
0f113f3e
MC
632{
633 return md->value;
634}
bc37d996 635
9dd5ae65 636void *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
0f113f3e
MC
637{
638 return md->usr_data;
639}
bc37d996
DSH
640
641void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
0f113f3e
MC
642{
643 md->usr_data = usr_data;
644}
bc37d996 645
9dd5ae65 646CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
0f113f3e
MC
647{
648 return md->pmod;
649}
bc37d996 650
9dd5ae65 651unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
0f113f3e
MC
652{
653 return md->flags;
654}
bc37d996
DSH
655
656void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
0f113f3e
MC
657{
658 md->flags = flags;
659}
bc37d996
DSH
660
661void *CONF_module_get_usr_data(CONF_MODULE *pmod)
0f113f3e
MC
662{
663 return pmod->usr_data;
664}
bc37d996
DSH
665
666void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
0f113f3e
MC
667{
668 pmod->usr_data = usr_data;
669}
bc37d996 670
c9501c22 671/* Return default config file name */
c9501c22 672char *CONF_get1_default_config_file(void)
0f113f3e 673{
e306f83c 674 const char *t;
a2371fa9 675 char *file, *sep = "";
e306f83c 676 size_t size;
c9501c22 677
5c39a55d
P
678 if ((file = ossl_safe_getenv("OPENSSL_CONF")) != NULL)
679 return OPENSSL_strdup(file);
c9501c22 680
e306f83c 681 t = X509_get_default_cert_area();
c9501c22 682#ifndef OPENSSL_SYS_VMS
a2371fa9 683 sep = "/";
c9501c22 684#endif
e306f83c
RL
685 size = strlen(t) + strlen(sep) + strlen(OPENSSL_CONF) + 1;
686 file = OPENSSL_malloc(size);
c9501c22 687
90945fa3 688 if (file == NULL)
0f113f3e 689 return NULL;
e306f83c 690 BIO_snprintf(file, size, "%s%s%s", t, sep, OPENSSL_CONF);
c9501c22 691
0f113f3e
MC
692 return file;
693}
df5eaa8a 694
0f113f3e
MC
695/*
696 * This function takes a list separated by 'sep' and calls the callback
697 * function giving the start and length of each member optionally stripping
698 * leading and trailing whitespace. This can be used to parse comma separated
699 * lists for example.
df5eaa8a
DSH
700 */
701
3822740c 702int CONF_parse_list(const char *list_, int sep, int nospc,
0f113f3e
MC
703 int (*list_cb) (const char *elem, int len, void *usr),
704 void *arg)
705{
706 int ret;
707 const char *lstart, *tmpend, *p;
708
709 if (list_ == NULL) {
9311d0c4 710 ERR_raise(ERR_LIB_CONF, CONF_R_LIST_CANNOT_BE_NULL);
0f113f3e
MC
711 return 0;
712 }
713
714 lstart = list_;
715 for (;;) {
716 if (nospc) {
717 while (*lstart && isspace((unsigned char)*lstart))
718 lstart++;
719 }
720 p = strchr(lstart, sep);
12a765a5 721 if (p == lstart || *lstart == '\0')
0f113f3e
MC
722 ret = list_cb(NULL, 0, arg);
723 else {
724 if (p)
725 tmpend = p - 1;
726 else
727 tmpend = lstart + strlen(lstart) - 1;
728 if (nospc) {
729 while (isspace((unsigned char)*tmpend))
730 tmpend--;
731 }
732 ret = list_cb(lstart, tmpend - lstart + 1, arg);
733 }
734 if (ret <= 0)
735 return ret;
736 if (p == NULL)
737 return 1;
738 lstart = p + 1;
739 }
740}