1109998Smarkm/* conf_mod.c */
2296341Sdelphij/*
3296341Sdelphij * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
4296341Sdelphij * 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
14296341Sdelphij *    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
71296341Sdelphij/*
72296341Sdelphij * This structure contains a data about supported modules. entries in this
73296341Sdelphij * table correspond to either dynamic or static modules.
74109998Smarkm */
75109998Smarkm
76296341Sdelphijstruct conf_module_st {
77296341Sdelphij    /* DSO of this module or NULL if static */
78296341Sdelphij    DSO *dso;
79296341Sdelphij    /* Name of the module */
80296341Sdelphij    char *name;
81296341Sdelphij    /* Init function */
82296341Sdelphij    conf_init_func *init;
83296341Sdelphij    /* Finish function */
84296341Sdelphij    conf_finish_func *finish;
85296341Sdelphij    /* Number of successfully initialized modules */
86296341Sdelphij    int links;
87296341Sdelphij    void *usr_data;
88296341Sdelphij};
89109998Smarkm
90296341Sdelphij/*
91296341Sdelphij * This structure contains information about modules that have been
92296341Sdelphij * successfully initialized. There may be more than one entry for a given
93296341Sdelphij * module.
94109998Smarkm */
95109998Smarkm
96296341Sdelphijstruct conf_imodule_st {
97296341Sdelphij    CONF_MODULE *pmod;
98296341Sdelphij    char *name;
99296341Sdelphij    char *value;
100296341Sdelphij    unsigned long flags;
101296341Sdelphij    void *usr_data;
102296341Sdelphij};
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,
110296341Sdelphij                      unsigned long flags);
111109998Smarkmstatic CONF_MODULE *module_add(DSO *dso, const char *name,
112296341Sdelphij                               conf_init_func *ifunc,
113296341Sdelphij                               conf_finish_func *ffunc);
114109998Smarkmstatic CONF_MODULE *module_find(char *name);
115109998Smarkmstatic int module_init(CONF_MODULE *pmod, char *name, char *value,
116296341Sdelphij                       const CONF *cnf);
117109998Smarkmstatic CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
118296341Sdelphij                                    unsigned long flags);
119109998Smarkm
120109998Smarkm/* Main function: load modules from a CONF structure */
121109998Smarkm
122109998Smarkmint CONF_modules_load(const CONF *cnf, const char *appname,
123296341Sdelphij                      unsigned long flags)
124296341Sdelphij{
125296341Sdelphij    STACK_OF(CONF_VALUE) *values;
126296341Sdelphij    CONF_VALUE *vl;
127296341Sdelphij    char *vsection = NULL;
128109998Smarkm
129296341Sdelphij    int ret, i;
130109998Smarkm
131296341Sdelphij    if (!cnf)
132296341Sdelphij        return 1;
133109998Smarkm
134296341Sdelphij    if (appname)
135296341Sdelphij        vsection = NCONF_get_string(cnf, NULL, appname);
136109998Smarkm
137296341Sdelphij    if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
138296341Sdelphij        vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
139109998Smarkm
140296341Sdelphij    if (!vsection) {
141296341Sdelphij        ERR_clear_error();
142296341Sdelphij        return 1;
143296341Sdelphij    }
144109998Smarkm
145296341Sdelphij    values = NCONF_get_section(cnf, vsection);
146109998Smarkm
147296341Sdelphij    if (!values)
148296341Sdelphij        return 0;
149109998Smarkm
150296341Sdelphij    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
151296341Sdelphij        vl = sk_CONF_VALUE_value(values, i);
152296341Sdelphij        ret = module_run(cnf, vl->name, vl->value, flags);
153296341Sdelphij        if (ret <= 0)
154296341Sdelphij            if (!(flags & CONF_MFLAGS_IGNORE_ERRORS))
155296341Sdelphij                return ret;
156296341Sdelphij    }
157109998Smarkm
158296341Sdelphij    return 1;
159109998Smarkm
160296341Sdelphij}
161109998Smarkm
162109998Smarkmint CONF_modules_load_file(const char *filename, const char *appname,
163296341Sdelphij                           unsigned long flags)
164296341Sdelphij{
165296341Sdelphij    char *file = NULL;
166296341Sdelphij    CONF *conf = NULL;
167296341Sdelphij    int ret = 0;
168296341Sdelphij    conf = NCONF_new(NULL);
169296341Sdelphij    if (!conf)
170296341Sdelphij        goto err;
171109998Smarkm
172296341Sdelphij    if (filename == NULL) {
173296341Sdelphij        file = CONF_get1_default_config_file();
174296341Sdelphij        if (!file)
175296341Sdelphij            goto err;
176296341Sdelphij    } else
177296341Sdelphij        file = (char *)filename;
178109998Smarkm
179296341Sdelphij    if (NCONF_load(conf, file, NULL) <= 0) {
180296341Sdelphij        if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
181296341Sdelphij            (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) {
182296341Sdelphij            ERR_clear_error();
183296341Sdelphij            ret = 1;
184296341Sdelphij        }
185296341Sdelphij        goto err;
186296341Sdelphij    }
187109998Smarkm
188296341Sdelphij    ret = CONF_modules_load(conf, appname, flags);
189109998Smarkm
190296341Sdelphij err:
191296341Sdelphij    if (filename == NULL)
192296341Sdelphij        OPENSSL_free(file);
193296341Sdelphij    NCONF_free(conf);
194109998Smarkm
195296341Sdelphij    return ret;
196296341Sdelphij}
197109998Smarkm
198109998Smarkmstatic int module_run(const CONF *cnf, char *name, char *value,
199296341Sdelphij                      unsigned long flags)
200296341Sdelphij{
201296341Sdelphij    CONF_MODULE *md;
202296341Sdelphij    int ret;
203109998Smarkm
204296341Sdelphij    md = module_find(name);
205109998Smarkm
206296341Sdelphij    /* Module not found: try to load DSO */
207296341Sdelphij    if (!md && !(flags & CONF_MFLAGS_NO_DSO))
208296341Sdelphij        md = module_load_dso(cnf, name, value, flags);
209109998Smarkm
210296341Sdelphij    if (!md) {
211296341Sdelphij        if (!(flags & CONF_MFLAGS_SILENT)) {
212296341Sdelphij            CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);
213296341Sdelphij            ERR_add_error_data(2, "module=", name);
214296341Sdelphij        }
215296341Sdelphij        return -1;
216296341Sdelphij    }
217109998Smarkm
218296341Sdelphij    ret = module_init(md, name, value, cnf);
219109998Smarkm
220296341Sdelphij    if (ret <= 0) {
221296341Sdelphij        if (!(flags & CONF_MFLAGS_SILENT)) {
222296341Sdelphij            char rcode[DECIMAL_SIZE(ret) + 1];
223296341Sdelphij            CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);
224296341Sdelphij            BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);
225296341Sdelphij            ERR_add_error_data(6, "module=", name, ", value=", value,
226296341Sdelphij                               ", retcode=", rcode);
227296341Sdelphij        }
228296341Sdelphij    }
229109998Smarkm
230296341Sdelphij    return ret;
231296341Sdelphij}
232109998Smarkm
233109998Smarkm/* Load a module from a DSO */
234109998Smarkmstatic CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
235296341Sdelphij                                    unsigned long flags)
236296341Sdelphij{
237296341Sdelphij    DSO *dso = NULL;
238296341Sdelphij    conf_init_func *ifunc;
239296341Sdelphij    conf_finish_func *ffunc;
240296341Sdelphij    char *path = NULL;
241296341Sdelphij    int errcode = 0;
242296341Sdelphij    CONF_MODULE *md;
243296341Sdelphij    /* Look for alternative path in module section */
244296341Sdelphij    path = NCONF_get_string(cnf, value, "path");
245296341Sdelphij    if (!path) {
246296341Sdelphij        ERR_clear_error();
247296341Sdelphij        path = name;
248296341Sdelphij    }
249296341Sdelphij    dso = DSO_load(NULL, path, NULL, 0);
250296341Sdelphij    if (!dso) {
251296341Sdelphij        errcode = CONF_R_ERROR_LOADING_DSO;
252296341Sdelphij        goto err;
253296341Sdelphij    }
254296341Sdelphij    ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
255296341Sdelphij    if (!ifunc) {
256296341Sdelphij        errcode = CONF_R_MISSING_INIT_FUNCTION;
257296341Sdelphij        goto err;
258296341Sdelphij    }
259296341Sdelphij    ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
260296341Sdelphij    /* All OK, add module */
261296341Sdelphij    md = module_add(dso, name, ifunc, ffunc);
262109998Smarkm
263296341Sdelphij    if (!md)
264296341Sdelphij        goto err;
265109998Smarkm
266296341Sdelphij    return md;
267109998Smarkm
268296341Sdelphij err:
269296341Sdelphij    if (dso)
270296341Sdelphij        DSO_free(dso);
271296341Sdelphij    CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);
272296341Sdelphij    ERR_add_error_data(4, "module=", name, ", path=", path);
273296341Sdelphij    return NULL;
274296341Sdelphij}
275109998Smarkm
276109998Smarkm/* add module to list */
277109998Smarkmstatic CONF_MODULE *module_add(DSO *dso, const char *name,
278296341Sdelphij                               conf_init_func *ifunc, conf_finish_func *ffunc)
279296341Sdelphij{
280296341Sdelphij    CONF_MODULE *tmod = NULL;
281296341Sdelphij    if (supported_modules == NULL)
282296341Sdelphij        supported_modules = sk_CONF_MODULE_new_null();
283296341Sdelphij    if (supported_modules == NULL)
284296341Sdelphij        return NULL;
285296341Sdelphij    tmod = OPENSSL_malloc(sizeof(CONF_MODULE));
286296341Sdelphij    if (tmod == NULL)
287296341Sdelphij        return NULL;
288109998Smarkm
289296341Sdelphij    tmod->dso = dso;
290296341Sdelphij    tmod->name = BUF_strdup(name);
291296341Sdelphij    tmod->init = ifunc;
292296341Sdelphij    tmod->finish = ffunc;
293296341Sdelphij    tmod->links = 0;
294109998Smarkm
295296341Sdelphij    if (!sk_CONF_MODULE_push(supported_modules, tmod)) {
296296341Sdelphij        OPENSSL_free(tmod);
297296341Sdelphij        return NULL;
298296341Sdelphij    }
299109998Smarkm
300296341Sdelphij    return tmod;
301296341Sdelphij}
302109998Smarkm
303296341Sdelphij/*
304296341Sdelphij * Find a module from the list. We allow module names of the form
305296341Sdelphij * modname.XXXX to just search for modname to allow the same module to be
306296341Sdelphij * initialized more than once.
307109998Smarkm */
308109998Smarkm
309109998Smarkmstatic CONF_MODULE *module_find(char *name)
310296341Sdelphij{
311296341Sdelphij    CONF_MODULE *tmod;
312296341Sdelphij    int i, nchar;
313296341Sdelphij    char *p;
314296341Sdelphij    p = strrchr(name, '.');
315109998Smarkm
316296341Sdelphij    if (p)
317296341Sdelphij        nchar = p - name;
318296341Sdelphij    else
319296341Sdelphij        nchar = strlen(name);
320109998Smarkm
321296341Sdelphij    for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) {
322296341Sdelphij        tmod = sk_CONF_MODULE_value(supported_modules, i);
323296341Sdelphij        if (!strncmp(tmod->name, name, nchar))
324296341Sdelphij            return tmod;
325296341Sdelphij    }
326109998Smarkm
327296341Sdelphij    return NULL;
328109998Smarkm
329296341Sdelphij}
330109998Smarkm
331109998Smarkm/* initialize a module */
332109998Smarkmstatic int module_init(CONF_MODULE *pmod, char *name, char *value,
333296341Sdelphij                       const CONF *cnf)
334296341Sdelphij{
335296341Sdelphij    int ret = 1;
336296341Sdelphij    int init_called = 0;
337296341Sdelphij    CONF_IMODULE *imod = NULL;
338109998Smarkm
339296341Sdelphij    /* Otherwise add initialized module to list */
340296341Sdelphij    imod = OPENSSL_malloc(sizeof(CONF_IMODULE));
341296341Sdelphij    if (!imod)
342296341Sdelphij        goto err;
343109998Smarkm
344296341Sdelphij    imod->pmod = pmod;
345296341Sdelphij    imod->name = BUF_strdup(name);
346296341Sdelphij    imod->value = BUF_strdup(value);
347296341Sdelphij    imod->usr_data = NULL;
348109998Smarkm
349296341Sdelphij    if (!imod->name || !imod->value)
350296341Sdelphij        goto memerr;
351109998Smarkm
352296341Sdelphij    /* Try to initialize module */
353296341Sdelphij    if (pmod->init) {
354296341Sdelphij        ret = pmod->init(imod, cnf);
355296341Sdelphij        init_called = 1;
356296341Sdelphij        /* Error occurred, exit */
357296341Sdelphij        if (ret <= 0)
358296341Sdelphij            goto err;
359296341Sdelphij    }
360109998Smarkm
361296341Sdelphij    if (initialized_modules == NULL) {
362296341Sdelphij        initialized_modules = sk_CONF_IMODULE_new_null();
363296341Sdelphij        if (!initialized_modules) {
364296341Sdelphij            CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
365296341Sdelphij            goto err;
366296341Sdelphij        }
367296341Sdelphij    }
368109998Smarkm
369296341Sdelphij    if (!sk_CONF_IMODULE_push(initialized_modules, imod)) {
370296341Sdelphij        CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
371296341Sdelphij        goto err;
372296341Sdelphij    }
373109998Smarkm
374296341Sdelphij    pmod->links++;
375109998Smarkm
376296341Sdelphij    return ret;
377109998Smarkm
378296341Sdelphij err:
379109998Smarkm
380296341Sdelphij    /* We've started the module so we'd better finish it */
381296341Sdelphij    if (pmod->finish && init_called)
382296341Sdelphij        pmod->finish(imod);
383109998Smarkm
384296341Sdelphij memerr:
385296341Sdelphij    if (imod) {
386296341Sdelphij        if (imod->name)
387296341Sdelphij            OPENSSL_free(imod->name);
388296341Sdelphij        if (imod->value)
389296341Sdelphij            OPENSSL_free(imod->value);
390296341Sdelphij        OPENSSL_free(imod);
391296341Sdelphij    }
392109998Smarkm
393296341Sdelphij    return -1;
394109998Smarkm
395296341Sdelphij}
396109998Smarkm
397296341Sdelphij/*
398296341Sdelphij * Unload any dynamic modules that have a link count of zero: i.e. have no
399296341Sdelphij * active initialized modules. If 'all' is set then all modules are unloaded
400296341Sdelphij * including static ones.
401109998Smarkm */
402109998Smarkm
403109998Smarkmvoid CONF_modules_unload(int all)
404296341Sdelphij{
405296341Sdelphij    int i;
406296341Sdelphij    CONF_MODULE *md;
407296341Sdelphij    CONF_modules_finish();
408296341Sdelphij    /* unload modules in reverse order */
409296341Sdelphij    for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) {
410296341Sdelphij        md = sk_CONF_MODULE_value(supported_modules, i);
411296341Sdelphij        /* If static or in use and 'all' not set ignore it */
412296341Sdelphij        if (((md->links > 0) || !md->dso) && !all)
413296341Sdelphij            continue;
414296341Sdelphij        /* Since we're working in reverse this is OK */
415296341Sdelphij        (void)sk_CONF_MODULE_delete(supported_modules, i);
416296341Sdelphij        module_free(md);
417296341Sdelphij    }
418296341Sdelphij    if (sk_CONF_MODULE_num(supported_modules) == 0) {
419296341Sdelphij        sk_CONF_MODULE_free(supported_modules);
420296341Sdelphij        supported_modules = NULL;
421296341Sdelphij    }
422296341Sdelphij}
423109998Smarkm
424109998Smarkm/* unload a single module */
425109998Smarkmstatic void module_free(CONF_MODULE *md)
426296341Sdelphij{
427296341Sdelphij    if (md->dso)
428296341Sdelphij        DSO_free(md->dso);
429296341Sdelphij    OPENSSL_free(md->name);
430296341Sdelphij    OPENSSL_free(md);
431296341Sdelphij}
432109998Smarkm
433109998Smarkm/* finish and free up all modules instances */
434109998Smarkm
435109998Smarkmvoid CONF_modules_finish(void)
436296341Sdelphij{
437296341Sdelphij    CONF_IMODULE *imod;
438296341Sdelphij    while (sk_CONF_IMODULE_num(initialized_modules) > 0) {
439296341Sdelphij        imod = sk_CONF_IMODULE_pop(initialized_modules);
440296341Sdelphij        module_finish(imod);
441296341Sdelphij    }
442296341Sdelphij    sk_CONF_IMODULE_free(initialized_modules);
443296341Sdelphij    initialized_modules = NULL;
444296341Sdelphij}
445109998Smarkm
446109998Smarkm/* finish a module instance */
447109998Smarkm
448109998Smarkmstatic void module_finish(CONF_IMODULE *imod)
449296341Sdelphij{
450296341Sdelphij    if (imod->pmod->finish)
451296341Sdelphij        imod->pmod->finish(imod);
452296341Sdelphij    imod->pmod->links--;
453296341Sdelphij    OPENSSL_free(imod->name);
454296341Sdelphij    OPENSSL_free(imod->value);
455296341Sdelphij    OPENSSL_free(imod);
456296341Sdelphij}
457109998Smarkm
458109998Smarkm/* Add a static module to OpenSSL */
459109998Smarkm
460296341Sdelphijint CONF_module_add(const char *name, conf_init_func *ifunc,
461296341Sdelphij                    conf_finish_func *ffunc)
462296341Sdelphij{
463296341Sdelphij    if (module_add(NULL, name, ifunc, ffunc))
464296341Sdelphij        return 1;
465296341Sdelphij    else
466296341Sdelphij        return 0;
467296341Sdelphij}
468109998Smarkm
469109998Smarkmvoid CONF_modules_free(void)
470296341Sdelphij{
471296341Sdelphij    CONF_modules_finish();
472296341Sdelphij    CONF_modules_unload(1);
473296341Sdelphij}
474109998Smarkm
475109998Smarkm/* Utility functions */
476109998Smarkm
477109998Smarkmconst char *CONF_imodule_get_name(const CONF_IMODULE *md)
478296341Sdelphij{
479296341Sdelphij    return md->name;
480296341Sdelphij}
481109998Smarkm
482109998Smarkmconst char *CONF_imodule_get_value(const CONF_IMODULE *md)
483296341Sdelphij{
484296341Sdelphij    return md->value;
485296341Sdelphij}
486109998Smarkm
487109998Smarkmvoid *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
488296341Sdelphij{
489296341Sdelphij    return md->usr_data;
490296341Sdelphij}
491109998Smarkm
492109998Smarkmvoid CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
493296341Sdelphij{
494296341Sdelphij    md->usr_data = usr_data;
495296341Sdelphij}
496109998Smarkm
497109998SmarkmCONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
498296341Sdelphij{
499296341Sdelphij    return md->pmod;
500296341Sdelphij}
501109998Smarkm
502109998Smarkmunsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
503296341Sdelphij{
504296341Sdelphij    return md->flags;
505296341Sdelphij}
506109998Smarkm
507109998Smarkmvoid CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
508296341Sdelphij{
509296341Sdelphij    md->flags = flags;
510296341Sdelphij}
511109998Smarkm
512109998Smarkmvoid *CONF_module_get_usr_data(CONF_MODULE *pmod)
513296341Sdelphij{
514296341Sdelphij    return pmod->usr_data;
515296341Sdelphij}
516109998Smarkm
517109998Smarkmvoid CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
518296341Sdelphij{
519296341Sdelphij    pmod->usr_data = usr_data;
520296341Sdelphij}
521109998Smarkm
522109998Smarkm/* Return default config file name */
523109998Smarkm
524109998Smarkmchar *CONF_get1_default_config_file(void)
525296341Sdelphij{
526296341Sdelphij    char *file;
527296341Sdelphij    int len;
528109998Smarkm
529296341Sdelphij    file = getenv("OPENSSL_CONF");
530296341Sdelphij    if (file)
531296341Sdelphij        return BUF_strdup(file);
532109998Smarkm
533296341Sdelphij    len = strlen(X509_get_default_cert_area());
534109998Smarkm#ifndef OPENSSL_SYS_VMS
535296341Sdelphij    len++;
536109998Smarkm#endif
537296341Sdelphij    len += strlen(OPENSSL_CONF);
538109998Smarkm
539296341Sdelphij    file = OPENSSL_malloc(len + 1);
540109998Smarkm
541296341Sdelphij    if (!file)
542296341Sdelphij        return NULL;
543296341Sdelphij    BUF_strlcpy(file, X509_get_default_cert_area(), len + 1);
544109998Smarkm#ifndef OPENSSL_SYS_VMS
545296341Sdelphij    BUF_strlcat(file, "/", len + 1);
546109998Smarkm#endif
547296341Sdelphij    BUF_strlcat(file, OPENSSL_CONF, len + 1);
548109998Smarkm
549296341Sdelphij    return file;
550296341Sdelphij}
551109998Smarkm
552296341Sdelphij/*
553296341Sdelphij * This function takes a list separated by 'sep' and calls the callback
554296341Sdelphij * function giving the start and length of each member optionally stripping
555296341Sdelphij * leading and trailing whitespace. This can be used to parse comma separated
556296341Sdelphij * lists for example.
557109998Smarkm */
558109998Smarkm
559127128Snectarint CONF_parse_list(const char *list_, int sep, int nospc,
560296341Sdelphij                    int (*list_cb) (const char *elem, int len, void *usr),
561296341Sdelphij                    void *arg)
562296341Sdelphij{
563296341Sdelphij    int ret;
564296341Sdelphij    const char *lstart, *tmpend, *p;
565238405Sjkim
566296341Sdelphij    if (list_ == NULL) {
567296341Sdelphij        CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
568296341Sdelphij        return 0;
569296341Sdelphij    }
570238405Sjkim
571296341Sdelphij    lstart = list_;
572296341Sdelphij    for (;;) {
573296341Sdelphij        if (nospc) {
574296341Sdelphij            while (*lstart && isspace((unsigned char)*lstart))
575296341Sdelphij                lstart++;
576296341Sdelphij        }
577296341Sdelphij        p = strchr(lstart, sep);
578296341Sdelphij        if (p == lstart || !*lstart)
579296341Sdelphij            ret = list_cb(NULL, 0, arg);
580296341Sdelphij        else {
581296341Sdelphij            if (p)
582296341Sdelphij                tmpend = p - 1;
583296341Sdelphij            else
584296341Sdelphij                tmpend = lstart + strlen(lstart) - 1;
585296341Sdelphij            if (nospc) {
586296341Sdelphij                while (isspace((unsigned char)*tmpend))
587296341Sdelphij                    tmpend--;
588296341Sdelphij            }
589296341Sdelphij            ret = list_cb(lstart, tmpend - lstart + 1, arg);
590296341Sdelphij        }
591296341Sdelphij        if (ret <= 0)
592296341Sdelphij            return ret;
593296341Sdelphij        if (p == NULL)
594296341Sdelphij            return 1;
595296341Sdelphij        lstart = p + 1;
596296341Sdelphij    }
597296341Sdelphij}
598