1109998Smarkm/* conf_mod.c */
2296465Sdelphij/*
3296465Sdelphij * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
4296465Sdelphij * 2001.
5109998Smarkm */
6109998Smarkm/* ====================================================================
7109998Smarkm * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
8109998Smarkm *
9109998Smarkm * Redistribution and use in source and binary forms, with or without
10109998Smarkm * modification, are permitted provided that the following conditions
11109998Smarkm * are met:
12109998Smarkm *
13109998Smarkm * 1. Redistributions of source code must retain the above copyright
14296465Sdelphij *    notice, this list of conditions and the following disclaimer.
15109998Smarkm *
16109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
17109998Smarkm *    notice, this list of conditions and the following disclaimer in
18109998Smarkm *    the documentation and/or other materials provided with the
19109998Smarkm *    distribution.
20109998Smarkm *
21109998Smarkm * 3. All advertising materials mentioning features or use of this
22109998Smarkm *    software must display the following acknowledgment:
23109998Smarkm *    "This product includes software developed by the OpenSSL Project
24109998Smarkm *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25109998Smarkm *
26109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27109998Smarkm *    endorse or promote products derived from this software without
28109998Smarkm *    prior written permission. For written permission, please contact
29109998Smarkm *    licensing@OpenSSL.org.
30109998Smarkm *
31109998Smarkm * 5. Products derived from this software may not be called "OpenSSL"
32109998Smarkm *    nor may "OpenSSL" appear in their names without prior written
33109998Smarkm *    permission of the OpenSSL Project.
34109998Smarkm *
35109998Smarkm * 6. Redistributions of any form whatsoever must retain the following
36109998Smarkm *    acknowledgment:
37109998Smarkm *    "This product includes software developed by the OpenSSL Project
38109998Smarkm *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39109998Smarkm *
40109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43109998Smarkm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE.
52109998Smarkm * ====================================================================
53109998Smarkm *
54109998Smarkm * This product includes cryptographic software written by Eric Young
55109998Smarkm * (eay@cryptsoft.com).  This product includes software written by Tim
56109998Smarkm * Hudson (tjh@cryptsoft.com).
57109998Smarkm *
58109998Smarkm */
59109998Smarkm
60109998Smarkm#include <stdio.h>
61109998Smarkm#include <ctype.h>
62109998Smarkm#include <openssl/crypto.h>
63109998Smarkm#include "cryptlib.h"
64109998Smarkm#include <openssl/conf.h>
65109998Smarkm#include <openssl/dso.h>
66109998Smarkm#include <openssl/x509.h>
67109998Smarkm
68109998Smarkm#define DSO_mod_init_name "OPENSSL_init"
69109998Smarkm#define DSO_mod_finish_name "OPENSSL_finish"
70109998Smarkm
71296465Sdelphij/*
72296465Sdelphij * This structure contains a data about supported modules. entries in this
73296465Sdelphij * table correspond to either dynamic or static modules.
74109998Smarkm */
75109998Smarkm
76296465Sdelphijstruct conf_module_st {
77296465Sdelphij    /* DSO of this module or NULL if static */
78296465Sdelphij    DSO *dso;
79296465Sdelphij    /* Name of the module */
80296465Sdelphij    char *name;
81296465Sdelphij    /* Init function */
82296465Sdelphij    conf_init_func *init;
83296465Sdelphij    /* Finish function */
84296465Sdelphij    conf_finish_func *finish;
85296465Sdelphij    /* Number of successfully initialized modules */
86296465Sdelphij    int links;
87296465Sdelphij    void *usr_data;
88296465Sdelphij};
89109998Smarkm
90296465Sdelphij/*
91296465Sdelphij * This structure contains information about modules that have been
92296465Sdelphij * successfully initialized. There may be more than one entry for a given
93296465Sdelphij * module.
94109998Smarkm */
95109998Smarkm
96296465Sdelphijstruct conf_imodule_st {
97296465Sdelphij    CONF_MODULE *pmod;
98296465Sdelphij    char *name;
99296465Sdelphij    char *value;
100296465Sdelphij    unsigned long flags;
101296465Sdelphij    void *usr_data;
102296465Sdelphij};
103109998Smarkm
104109998Smarkmstatic STACK_OF(CONF_MODULE) *supported_modules = NULL;
105109998Smarkmstatic STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
106109998Smarkm
107109998Smarkmstatic void module_free(CONF_MODULE *md);
108109998Smarkmstatic void module_finish(CONF_IMODULE *imod);
109109998Smarkmstatic int module_run(const CONF *cnf, char *name, char *value,
110296465Sdelphij                      unsigned long flags);
111109998Smarkmstatic CONF_MODULE *module_add(DSO *dso, const char *name,
112296465Sdelphij                               conf_init_func *ifunc,
113296465Sdelphij                               conf_finish_func *ffunc);
114109998Smarkmstatic CONF_MODULE *module_find(char *name);
115109998Smarkmstatic int module_init(CONF_MODULE *pmod, char *name, char *value,
116296465Sdelphij                       const CONF *cnf);
117109998Smarkmstatic CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
118296465Sdelphij                                    unsigned long flags);
119109998Smarkm
120109998Smarkm/* Main function: load modules from a CONF structure */
121109998Smarkm
122109998Smarkmint CONF_modules_load(const CONF *cnf, const char *appname,
123296465Sdelphij                      unsigned long flags)
124296465Sdelphij{
125296465Sdelphij    STACK_OF(CONF_VALUE) *values;
126296465Sdelphij    CONF_VALUE *vl;
127296465Sdelphij    char *vsection = NULL;
128109998Smarkm
129296465Sdelphij    int ret, i;
130109998Smarkm
131296465Sdelphij    if (!cnf)
132296465Sdelphij        return 1;
133109998Smarkm
134296465Sdelphij    if (appname)
135296465Sdelphij        vsection = NCONF_get_string(cnf, NULL, appname);
136109998Smarkm
137296465Sdelphij    if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
138296465Sdelphij        vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
139109998Smarkm
140296465Sdelphij    if (!vsection) {
141296465Sdelphij        ERR_clear_error();
142296465Sdelphij        return 1;
143296465Sdelphij    }
144109998Smarkm
145296465Sdelphij    values = NCONF_get_section(cnf, vsection);
146109998Smarkm
147296465Sdelphij    if (!values)
148296465Sdelphij        return 0;
149109998Smarkm
150296465Sdelphij    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
151296465Sdelphij        vl = sk_CONF_VALUE_value(values, i);
152296465Sdelphij        ret = module_run(cnf, vl->name, vl->value, flags);
153296465Sdelphij        if (ret <= 0)
154296465Sdelphij            if (!(flags & CONF_MFLAGS_IGNORE_ERRORS))
155296465Sdelphij                return ret;
156296465Sdelphij    }
157109998Smarkm
158296465Sdelphij    return 1;
159109998Smarkm
160296465Sdelphij}
161109998Smarkm
162109998Smarkmint CONF_modules_load_file(const char *filename, const char *appname,
163296465Sdelphij                           unsigned long flags)
164296465Sdelphij{
165296465Sdelphij    char *file = NULL;
166296465Sdelphij    CONF *conf = NULL;
167296465Sdelphij    int ret = 0;
168296465Sdelphij    conf = NCONF_new(NULL);
169296465Sdelphij    if (!conf)
170296465Sdelphij        goto err;
171109998Smarkm
172296465Sdelphij    if (filename == NULL) {
173296465Sdelphij        file = CONF_get1_default_config_file();
174296465Sdelphij        if (!file)
175296465Sdelphij            goto err;
176296465Sdelphij    } else
177296465Sdelphij        file = (char *)filename;
178109998Smarkm
179296465Sdelphij    if (NCONF_load(conf, file, NULL) <= 0) {
180296465Sdelphij        if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
181296465Sdelphij            (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) {
182296465Sdelphij            ERR_clear_error();
183296465Sdelphij            ret = 1;
184296465Sdelphij        }
185296465Sdelphij        goto err;
186296465Sdelphij    }
187109998Smarkm
188296465Sdelphij    ret = CONF_modules_load(conf, appname, flags);
189109998Smarkm
190296465Sdelphij err:
191296465Sdelphij    if (filename == NULL)
192296465Sdelphij        OPENSSL_free(file);
193296465Sdelphij    NCONF_free(conf);
194109998Smarkm
195296465Sdelphij    return ret;
196296465Sdelphij}
197109998Smarkm
198109998Smarkmstatic int module_run(const CONF *cnf, char *name, char *value,
199296465Sdelphij                      unsigned long flags)
200296465Sdelphij{
201296465Sdelphij    CONF_MODULE *md;
202296465Sdelphij    int ret;
203109998Smarkm
204296465Sdelphij    md = module_find(name);
205109998Smarkm
206296465Sdelphij    /* Module not found: try to load DSO */
207296465Sdelphij    if (!md && !(flags & CONF_MFLAGS_NO_DSO))
208296465Sdelphij        md = module_load_dso(cnf, name, value, flags);
209109998Smarkm
210296465Sdelphij    if (!md) {
211296465Sdelphij        if (!(flags & CONF_MFLAGS_SILENT)) {
212296465Sdelphij            CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);
213296465Sdelphij            ERR_add_error_data(2, "module=", name);
214296465Sdelphij        }
215296465Sdelphij        return -1;
216296465Sdelphij    }
217109998Smarkm
218296465Sdelphij    ret = module_init(md, name, value, cnf);
219109998Smarkm
220296465Sdelphij    if (ret <= 0) {
221296465Sdelphij        if (!(flags & CONF_MFLAGS_SILENT)) {
222296465Sdelphij            char rcode[DECIMAL_SIZE(ret) + 1];
223296465Sdelphij            CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);
224296465Sdelphij            BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);
225296465Sdelphij            ERR_add_error_data(6, "module=", name, ", value=", value,
226296465Sdelphij                               ", retcode=", rcode);
227296465Sdelphij        }
228296465Sdelphij    }
229109998Smarkm
230296465Sdelphij    return ret;
231296465Sdelphij}
232109998Smarkm
233109998Smarkm/* Load a module from a DSO */
234109998Smarkmstatic CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
235296465Sdelphij                                    unsigned long flags)
236296465Sdelphij{
237296465Sdelphij    DSO *dso = NULL;
238296465Sdelphij    conf_init_func *ifunc;
239296465Sdelphij    conf_finish_func *ffunc;
240296465Sdelphij    char *path = NULL;
241296465Sdelphij    int errcode = 0;
242296465Sdelphij    CONF_MODULE *md;
243296465Sdelphij    /* Look for alternative path in module section */
244296465Sdelphij    path = NCONF_get_string(cnf, value, "path");
245296465Sdelphij    if (!path) {
246296465Sdelphij        ERR_clear_error();
247296465Sdelphij        path = name;
248296465Sdelphij    }
249296465Sdelphij    dso = DSO_load(NULL, path, NULL, 0);
250296465Sdelphij    if (!dso) {
251296465Sdelphij        errcode = CONF_R_ERROR_LOADING_DSO;
252296465Sdelphij        goto err;
253296465Sdelphij    }
254296465Sdelphij    ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
255296465Sdelphij    if (!ifunc) {
256296465Sdelphij        errcode = CONF_R_MISSING_INIT_FUNCTION;
257296465Sdelphij        goto err;
258296465Sdelphij    }
259296465Sdelphij    ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
260296465Sdelphij    /* All OK, add module */
261296465Sdelphij    md = module_add(dso, name, ifunc, ffunc);
262109998Smarkm
263296465Sdelphij    if (!md)
264296465Sdelphij        goto err;
265109998Smarkm
266296465Sdelphij    return md;
267109998Smarkm
268296465Sdelphij err:
269296465Sdelphij    if (dso)
270296465Sdelphij        DSO_free(dso);
271296465Sdelphij    CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);
272296465Sdelphij    ERR_add_error_data(4, "module=", name, ", path=", path);
273296465Sdelphij    return NULL;
274296465Sdelphij}
275109998Smarkm
276109998Smarkm/* add module to list */
277109998Smarkmstatic CONF_MODULE *module_add(DSO *dso, const char *name,
278296465Sdelphij                               conf_init_func *ifunc, conf_finish_func *ffunc)
279296465Sdelphij{
280296465Sdelphij    CONF_MODULE *tmod = NULL;
281296465Sdelphij    if (supported_modules == NULL)
282296465Sdelphij        supported_modules = sk_CONF_MODULE_new_null();
283296465Sdelphij    if (supported_modules == NULL)
284296465Sdelphij        return NULL;
285296465Sdelphij    tmod = OPENSSL_malloc(sizeof(CONF_MODULE));
286296465Sdelphij    if (tmod == NULL)
287296465Sdelphij        return NULL;
288109998Smarkm
289296465Sdelphij    tmod->dso = dso;
290296465Sdelphij    tmod->name = BUF_strdup(name);
291296465Sdelphij    tmod->init = ifunc;
292296465Sdelphij    tmod->finish = ffunc;
293296465Sdelphij    tmod->links = 0;
294109998Smarkm
295296465Sdelphij    if (!sk_CONF_MODULE_push(supported_modules, tmod)) {
296296465Sdelphij        OPENSSL_free(tmod);
297296465Sdelphij        return NULL;
298296465Sdelphij    }
299109998Smarkm
300296465Sdelphij    return tmod;
301296465Sdelphij}
302109998Smarkm
303296465Sdelphij/*
304296465Sdelphij * Find a module from the list. We allow module names of the form
305296465Sdelphij * modname.XXXX to just search for modname to allow the same module to be
306296465Sdelphij * initialized more than once.
307109998Smarkm */
308109998Smarkm
309109998Smarkmstatic CONF_MODULE *module_find(char *name)
310296465Sdelphij{
311296465Sdelphij    CONF_MODULE *tmod;
312296465Sdelphij    int i, nchar;
313296465Sdelphij    char *p;
314296465Sdelphij    p = strrchr(name, '.');
315109998Smarkm
316296465Sdelphij    if (p)
317296465Sdelphij        nchar = p - name;
318296465Sdelphij    else
319296465Sdelphij        nchar = strlen(name);
320109998Smarkm
321296465Sdelphij    for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) {
322296465Sdelphij        tmod = sk_CONF_MODULE_value(supported_modules, i);
323296465Sdelphij        if (!strncmp(tmod->name, name, nchar))
324296465Sdelphij            return tmod;
325296465Sdelphij    }
326109998Smarkm
327296465Sdelphij    return NULL;
328109998Smarkm
329296465Sdelphij}
330109998Smarkm
331109998Smarkm/* initialize a module */
332109998Smarkmstatic int module_init(CONF_MODULE *pmod, char *name, char *value,
333296465Sdelphij                       const CONF *cnf)
334296465Sdelphij{
335296465Sdelphij    int ret = 1;
336296465Sdelphij    int init_called = 0;
337296465Sdelphij    CONF_IMODULE *imod = NULL;
338109998Smarkm
339296465Sdelphij    /* Otherwise add initialized module to list */
340296465Sdelphij    imod = OPENSSL_malloc(sizeof(CONF_IMODULE));
341296465Sdelphij    if (!imod)
342296465Sdelphij        goto err;
343109998Smarkm
344296465Sdelphij    imod->pmod = pmod;
345296465Sdelphij    imod->name = BUF_strdup(name);
346296465Sdelphij    imod->value = BUF_strdup(value);
347296465Sdelphij    imod->usr_data = NULL;
348109998Smarkm
349296465Sdelphij    if (!imod->name || !imod->value)
350296465Sdelphij        goto memerr;
351109998Smarkm
352296465Sdelphij    /* Try to initialize module */
353296465Sdelphij    if (pmod->init) {
354296465Sdelphij        ret = pmod->init(imod, cnf);
355296465Sdelphij        init_called = 1;
356296465Sdelphij        /* Error occurred, exit */
357296465Sdelphij        if (ret <= 0)
358296465Sdelphij            goto err;
359296465Sdelphij    }
360109998Smarkm
361296465Sdelphij    if (initialized_modules == NULL) {
362296465Sdelphij        initialized_modules = sk_CONF_IMODULE_new_null();
363296465Sdelphij        if (!initialized_modules) {
364296465Sdelphij            CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
365296465Sdelphij            goto err;
366296465Sdelphij        }
367296465Sdelphij    }
368109998Smarkm
369296465Sdelphij    if (!sk_CONF_IMODULE_push(initialized_modules, imod)) {
370296465Sdelphij        CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
371296465Sdelphij        goto err;
372296465Sdelphij    }
373109998Smarkm
374296465Sdelphij    pmod->links++;
375109998Smarkm
376296465Sdelphij    return ret;
377109998Smarkm
378296465Sdelphij err:
379109998Smarkm
380296465Sdelphij    /* We've started the module so we'd better finish it */
381296465Sdelphij    if (pmod->finish && init_called)
382296465Sdelphij        pmod->finish(imod);
383109998Smarkm
384296465Sdelphij memerr:
385296465Sdelphij    if (imod) {
386296465Sdelphij        if (imod->name)
387296465Sdelphij            OPENSSL_free(imod->name);
388296465Sdelphij        if (imod->value)
389296465Sdelphij            OPENSSL_free(imod->value);
390296465Sdelphij        OPENSSL_free(imod);
391296465Sdelphij    }
392109998Smarkm
393296465Sdelphij    return -1;
394109998Smarkm
395296465Sdelphij}
396109998Smarkm
397296465Sdelphij/*
398296465Sdelphij * Unload any dynamic modules that have a link count of zero: i.e. have no
399296465Sdelphij * active initialized modules. If 'all' is set then all modules are unloaded
400296465Sdelphij * including static ones.
401109998Smarkm */
402109998Smarkm
403109998Smarkmvoid CONF_modules_unload(int all)
404296465Sdelphij{
405296465Sdelphij    int i;
406296465Sdelphij    CONF_MODULE *md;
407296465Sdelphij    CONF_modules_finish();
408296465Sdelphij    /* unload modules in reverse order */
409296465Sdelphij    for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) {
410296465Sdelphij        md = sk_CONF_MODULE_value(supported_modules, i);
411296465Sdelphij        /* If static or in use and 'all' not set ignore it */
412296465Sdelphij        if (((md->links > 0) || !md->dso) && !all)
413296465Sdelphij            continue;
414296465Sdelphij        /* Since we're working in reverse this is OK */
415296465Sdelphij        (void)sk_CONF_MODULE_delete(supported_modules, i);
416296465Sdelphij        module_free(md);
417296465Sdelphij    }
418296465Sdelphij    if (sk_CONF_MODULE_num(supported_modules) == 0) {
419296465Sdelphij        sk_CONF_MODULE_free(supported_modules);
420296465Sdelphij        supported_modules = NULL;
421296465Sdelphij    }
422296465Sdelphij}
423109998Smarkm
424109998Smarkm/* unload a single module */
425109998Smarkmstatic void module_free(CONF_MODULE *md)
426296465Sdelphij{
427296465Sdelphij    if (md->dso)
428296465Sdelphij        DSO_free(md->dso);
429296465Sdelphij    OPENSSL_free(md->name);
430296465Sdelphij    OPENSSL_free(md);
431296465Sdelphij}
432109998Smarkm
433109998Smarkm/* finish and free up all modules instances */
434109998Smarkm
435109998Smarkmvoid CONF_modules_finish(void)
436296465Sdelphij{
437296465Sdelphij    CONF_IMODULE *imod;
438296465Sdelphij    while (sk_CONF_IMODULE_num(initialized_modules) > 0) {
439296465Sdelphij        imod = sk_CONF_IMODULE_pop(initialized_modules);
440296465Sdelphij        module_finish(imod);
441296465Sdelphij    }
442296465Sdelphij    sk_CONF_IMODULE_free(initialized_modules);
443296465Sdelphij    initialized_modules = NULL;
444296465Sdelphij}
445109998Smarkm
446109998Smarkm/* finish a module instance */
447109998Smarkm
448109998Smarkmstatic void module_finish(CONF_IMODULE *imod)
449296465Sdelphij{
450296465Sdelphij    if (imod->pmod->finish)
451296465Sdelphij        imod->pmod->finish(imod);
452296465Sdelphij    imod->pmod->links--;
453296465Sdelphij    OPENSSL_free(imod->name);
454296465Sdelphij    OPENSSL_free(imod->value);
455296465Sdelphij    OPENSSL_free(imod);
456296465Sdelphij}
457109998Smarkm
458109998Smarkm/* Add a static module to OpenSSL */
459109998Smarkm
460296465Sdelphijint CONF_module_add(const char *name, conf_init_func *ifunc,
461296465Sdelphij                    conf_finish_func *ffunc)
462296465Sdelphij{
463296465Sdelphij    if (module_add(NULL, name, ifunc, ffunc))
464296465Sdelphij        return 1;
465296465Sdelphij    else
466296465Sdelphij        return 0;
467296465Sdelphij}
468109998Smarkm
469109998Smarkmvoid CONF_modules_free(void)
470296465Sdelphij{
471296465Sdelphij    CONF_modules_finish();
472296465Sdelphij    CONF_modules_unload(1);
473296465Sdelphij}
474109998Smarkm
475109998Smarkm/* Utility functions */
476109998Smarkm
477109998Smarkmconst char *CONF_imodule_get_name(const CONF_IMODULE *md)
478296465Sdelphij{
479296465Sdelphij    return md->name;
480296465Sdelphij}
481109998Smarkm
482109998Smarkmconst char *CONF_imodule_get_value(const CONF_IMODULE *md)
483296465Sdelphij{
484296465Sdelphij    return md->value;
485296465Sdelphij}
486109998Smarkm
487109998Smarkmvoid *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
488296465Sdelphij{
489296465Sdelphij    return md->usr_data;
490296465Sdelphij}
491109998Smarkm
492109998Smarkmvoid CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
493296465Sdelphij{
494296465Sdelphij    md->usr_data = usr_data;
495296465Sdelphij}
496109998Smarkm
497109998SmarkmCONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
498296465Sdelphij{
499296465Sdelphij    return md->pmod;
500296465Sdelphij}
501109998Smarkm
502109998Smarkmunsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
503296465Sdelphij{
504296465Sdelphij    return md->flags;
505296465Sdelphij}
506109998Smarkm
507109998Smarkmvoid CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
508296465Sdelphij{
509296465Sdelphij    md->flags = flags;
510296465Sdelphij}
511109998Smarkm
512109998Smarkmvoid *CONF_module_get_usr_data(CONF_MODULE *pmod)
513296465Sdelphij{
514296465Sdelphij    return pmod->usr_data;
515296465Sdelphij}
516109998Smarkm
517109998Smarkmvoid CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
518296465Sdelphij{
519296465Sdelphij    pmod->usr_data = usr_data;
520296465Sdelphij}
521109998Smarkm
522109998Smarkm/* Return default config file name */
523109998Smarkm
524109998Smarkmchar *CONF_get1_default_config_file(void)
525296465Sdelphij{
526296465Sdelphij    char *file;
527296465Sdelphij    int len;
528109998Smarkm
529296465Sdelphij    file = getenv("OPENSSL_CONF");
530296465Sdelphij    if (file)
531296465Sdelphij        return BUF_strdup(file);
532109998Smarkm
533296465Sdelphij    len = strlen(X509_get_default_cert_area());
534109998Smarkm#ifndef OPENSSL_SYS_VMS
535296465Sdelphij    len++;
536109998Smarkm#endif
537296465Sdelphij    len += strlen(OPENSSL_CONF);
538109998Smarkm
539296465Sdelphij    file = OPENSSL_malloc(len + 1);
540109998Smarkm
541296465Sdelphij    if (!file)
542296465Sdelphij        return NULL;
543296465Sdelphij    BUF_strlcpy(file, X509_get_default_cert_area(), len + 1);
544109998Smarkm#ifndef OPENSSL_SYS_VMS
545296465Sdelphij    BUF_strlcat(file, "/", len + 1);
546109998Smarkm#endif
547296465Sdelphij    BUF_strlcat(file, OPENSSL_CONF, len + 1);
548109998Smarkm
549296465Sdelphij    return file;
550296465Sdelphij}
551109998Smarkm
552296465Sdelphij/*
553296465Sdelphij * This function takes a list separated by 'sep' and calls the callback
554296465Sdelphij * function giving the start and length of each member optionally stripping
555296465Sdelphij * leading and trailing whitespace. This can be used to parse comma separated
556296465Sdelphij * lists for example.
557109998Smarkm */
558109998Smarkm
559127128Snectarint CONF_parse_list(const char *list_, int sep, int nospc,
560296465Sdelphij                    int (*list_cb) (const char *elem, int len, void *usr),
561296465Sdelphij                    void *arg)
562296465Sdelphij{
563296465Sdelphij    int ret;
564296465Sdelphij    const char *lstart, *tmpend, *p;
565296465Sdelphij    lstart = list_;
566109998Smarkm
567296465Sdelphij    for (;;) {
568296465Sdelphij        if (nospc) {
569296465Sdelphij            while (*lstart && isspace((unsigned char)*lstart))
570296465Sdelphij                lstart++;
571296465Sdelphij        }
572296465Sdelphij        p = strchr(lstart, sep);
573296465Sdelphij        if (p == lstart || !*lstart)
574296465Sdelphij            ret = list_cb(NULL, 0, arg);
575296465Sdelphij        else {
576296465Sdelphij            if (p)
577296465Sdelphij                tmpend = p - 1;
578296465Sdelphij            else
579296465Sdelphij                tmpend = lstart + strlen(lstart) - 1;
580296465Sdelphij            if (nospc) {
581296465Sdelphij                while (isspace((unsigned char)*tmpend))
582296465Sdelphij                    tmpend--;
583296465Sdelphij            }
584296465Sdelphij            ret = list_cb(lstart, tmpend - lstart + 1, arg);
585296465Sdelphij        }
586296465Sdelphij        if (ret <= 0)
587296465Sdelphij            return ret;
588296465Sdelphij        if (p == NULL)
589296465Sdelphij            return 1;
590296465Sdelphij        lstart = p + 1;
591296465Sdelphij    }
592296465Sdelphij}
593