1109998Smarkm/* conf_mod.c */
2280304Sjkim/*
3280304Sjkim * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
4280304Sjkim * 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
14280304Sjkim *    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
71280304Sjkim/*
72280304Sjkim * This structure contains a data about supported modules. entries in this
73280304Sjkim * table correspond to either dynamic or static modules.
74109998Smarkm */
75109998Smarkm
76280304Sjkimstruct conf_module_st {
77280304Sjkim    /* DSO of this module or NULL if static */
78280304Sjkim    DSO *dso;
79280304Sjkim    /* Name of the module */
80280304Sjkim    char *name;
81280304Sjkim    /* Init function */
82280304Sjkim    conf_init_func *init;
83280304Sjkim    /* Finish function */
84280304Sjkim    conf_finish_func *finish;
85280304Sjkim    /* Number of successfully initialized modules */
86280304Sjkim    int links;
87280304Sjkim    void *usr_data;
88280304Sjkim};
89109998Smarkm
90280304Sjkim/*
91280304Sjkim * This structure contains information about modules that have been
92280304Sjkim * successfully initialized. There may be more than one entry for a given
93280304Sjkim * module.
94109998Smarkm */
95109998Smarkm
96280304Sjkimstruct conf_imodule_st {
97280304Sjkim    CONF_MODULE *pmod;
98280304Sjkim    char *name;
99280304Sjkim    char *value;
100280304Sjkim    unsigned long flags;
101280304Sjkim    void *usr_data;
102280304Sjkim};
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,
110280304Sjkim                      unsigned long flags);
111109998Smarkmstatic CONF_MODULE *module_add(DSO *dso, const char *name,
112280304Sjkim                               conf_init_func *ifunc,
113280304Sjkim                               conf_finish_func *ffunc);
114109998Smarkmstatic CONF_MODULE *module_find(char *name);
115109998Smarkmstatic int module_init(CONF_MODULE *pmod, char *name, char *value,
116280304Sjkim                       const CONF *cnf);
117109998Smarkmstatic CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
118280304Sjkim                                    unsigned long flags);
119109998Smarkm
120109998Smarkm/* Main function: load modules from a CONF structure */
121109998Smarkm
122109998Smarkmint CONF_modules_load(const CONF *cnf, const char *appname,
123280304Sjkim                      unsigned long flags)
124280304Sjkim{
125280304Sjkim    STACK_OF(CONF_VALUE) *values;
126280304Sjkim    CONF_VALUE *vl;
127280304Sjkim    char *vsection = NULL;
128109998Smarkm
129280304Sjkim    int ret, i;
130109998Smarkm
131280304Sjkim    if (!cnf)
132280304Sjkim        return 1;
133109998Smarkm
134280304Sjkim    if (appname)
135280304Sjkim        vsection = NCONF_get_string(cnf, NULL, appname);
136109998Smarkm
137280304Sjkim    if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
138280304Sjkim        vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
139109998Smarkm
140280304Sjkim    if (!vsection) {
141280304Sjkim        ERR_clear_error();
142280304Sjkim        return 1;
143280304Sjkim    }
144109998Smarkm
145280304Sjkim    values = NCONF_get_section(cnf, vsection);
146109998Smarkm
147280304Sjkim    if (!values)
148280304Sjkim        return 0;
149109998Smarkm
150280304Sjkim    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
151280304Sjkim        vl = sk_CONF_VALUE_value(values, i);
152280304Sjkim        ret = module_run(cnf, vl->name, vl->value, flags);
153280304Sjkim        if (ret <= 0)
154280304Sjkim            if (!(flags & CONF_MFLAGS_IGNORE_ERRORS))
155280304Sjkim                return ret;
156280304Sjkim    }
157109998Smarkm
158280304Sjkim    return 1;
159109998Smarkm
160280304Sjkim}
161109998Smarkm
162109998Smarkmint CONF_modules_load_file(const char *filename, const char *appname,
163280304Sjkim                           unsigned long flags)
164280304Sjkim{
165280304Sjkim    char *file = NULL;
166280304Sjkim    CONF *conf = NULL;
167280304Sjkim    int ret = 0;
168280304Sjkim    conf = NCONF_new(NULL);
169280304Sjkim    if (!conf)
170280304Sjkim        goto err;
171109998Smarkm
172280304Sjkim    if (filename == NULL) {
173280304Sjkim        file = CONF_get1_default_config_file();
174280304Sjkim        if (!file)
175280304Sjkim            goto err;
176280304Sjkim    } else
177280304Sjkim        file = (char *)filename;
178109998Smarkm
179280304Sjkim    if (NCONF_load(conf, file, NULL) <= 0) {
180280304Sjkim        if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
181280304Sjkim            (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) {
182280304Sjkim            ERR_clear_error();
183280304Sjkim            ret = 1;
184280304Sjkim        }
185280304Sjkim        goto err;
186280304Sjkim    }
187109998Smarkm
188280304Sjkim    ret = CONF_modules_load(conf, appname, flags);
189109998Smarkm
190280304Sjkim err:
191280304Sjkim    if (filename == NULL)
192280304Sjkim        OPENSSL_free(file);
193280304Sjkim    NCONF_free(conf);
194109998Smarkm
195280304Sjkim    return ret;
196280304Sjkim}
197109998Smarkm
198109998Smarkmstatic int module_run(const CONF *cnf, char *name, char *value,
199280304Sjkim                      unsigned long flags)
200280304Sjkim{
201280304Sjkim    CONF_MODULE *md;
202280304Sjkim    int ret;
203109998Smarkm
204280304Sjkim    md = module_find(name);
205109998Smarkm
206280304Sjkim    /* Module not found: try to load DSO */
207280304Sjkim    if (!md && !(flags & CONF_MFLAGS_NO_DSO))
208280304Sjkim        md = module_load_dso(cnf, name, value, flags);
209109998Smarkm
210280304Sjkim    if (!md) {
211280304Sjkim        if (!(flags & CONF_MFLAGS_SILENT)) {
212280304Sjkim            CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);
213280304Sjkim            ERR_add_error_data(2, "module=", name);
214280304Sjkim        }
215280304Sjkim        return -1;
216280304Sjkim    }
217109998Smarkm
218280304Sjkim    ret = module_init(md, name, value, cnf);
219109998Smarkm
220280304Sjkim    if (ret <= 0) {
221280304Sjkim        if (!(flags & CONF_MFLAGS_SILENT)) {
222280304Sjkim            char rcode[DECIMAL_SIZE(ret) + 1];
223280304Sjkim            CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);
224280304Sjkim            BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);
225280304Sjkim            ERR_add_error_data(6, "module=", name, ", value=", value,
226280304Sjkim                               ", retcode=", rcode);
227280304Sjkim        }
228280304Sjkim    }
229109998Smarkm
230280304Sjkim    return ret;
231280304Sjkim}
232109998Smarkm
233109998Smarkm/* Load a module from a DSO */
234109998Smarkmstatic CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
235280304Sjkim                                    unsigned long flags)
236280304Sjkim{
237280304Sjkim    DSO *dso = NULL;
238280304Sjkim    conf_init_func *ifunc;
239280304Sjkim    conf_finish_func *ffunc;
240280304Sjkim    char *path = NULL;
241280304Sjkim    int errcode = 0;
242280304Sjkim    CONF_MODULE *md;
243280304Sjkim    /* Look for alternative path in module section */
244280304Sjkim    path = NCONF_get_string(cnf, value, "path");
245280304Sjkim    if (!path) {
246280304Sjkim        ERR_clear_error();
247280304Sjkim        path = name;
248280304Sjkim    }
249280304Sjkim    dso = DSO_load(NULL, path, NULL, 0);
250280304Sjkim    if (!dso) {
251280304Sjkim        errcode = CONF_R_ERROR_LOADING_DSO;
252280304Sjkim        goto err;
253280304Sjkim    }
254280304Sjkim    ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
255280304Sjkim    if (!ifunc) {
256280304Sjkim        errcode = CONF_R_MISSING_INIT_FUNCTION;
257280304Sjkim        goto err;
258280304Sjkim    }
259280304Sjkim    ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
260280304Sjkim    /* All OK, add module */
261280304Sjkim    md = module_add(dso, name, ifunc, ffunc);
262109998Smarkm
263280304Sjkim    if (!md)
264280304Sjkim        goto err;
265109998Smarkm
266280304Sjkim    return md;
267109998Smarkm
268280304Sjkim err:
269280304Sjkim    if (dso)
270280304Sjkim        DSO_free(dso);
271280304Sjkim    CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);
272280304Sjkim    ERR_add_error_data(4, "module=", name, ", path=", path);
273280304Sjkim    return NULL;
274280304Sjkim}
275109998Smarkm
276109998Smarkm/* add module to list */
277109998Smarkmstatic CONF_MODULE *module_add(DSO *dso, const char *name,
278280304Sjkim                               conf_init_func *ifunc, conf_finish_func *ffunc)
279280304Sjkim{
280280304Sjkim    CONF_MODULE *tmod = NULL;
281280304Sjkim    if (supported_modules == NULL)
282280304Sjkim        supported_modules = sk_CONF_MODULE_new_null();
283280304Sjkim    if (supported_modules == NULL)
284280304Sjkim        return NULL;
285280304Sjkim    tmod = OPENSSL_malloc(sizeof(CONF_MODULE));
286280304Sjkim    if (tmod == NULL)
287280304Sjkim        return NULL;
288109998Smarkm
289280304Sjkim    tmod->dso = dso;
290280304Sjkim    tmod->name = BUF_strdup(name);
291280304Sjkim    tmod->init = ifunc;
292280304Sjkim    tmod->finish = ffunc;
293280304Sjkim    tmod->links = 0;
294109998Smarkm
295280304Sjkim    if (!sk_CONF_MODULE_push(supported_modules, tmod)) {
296280304Sjkim        OPENSSL_free(tmod);
297280304Sjkim        return NULL;
298280304Sjkim    }
299109998Smarkm
300280304Sjkim    return tmod;
301280304Sjkim}
302109998Smarkm
303280304Sjkim/*
304280304Sjkim * Find a module from the list. We allow module names of the form
305280304Sjkim * modname.XXXX to just search for modname to allow the same module to be
306280304Sjkim * initialized more than once.
307109998Smarkm */
308109998Smarkm
309109998Smarkmstatic CONF_MODULE *module_find(char *name)
310280304Sjkim{
311280304Sjkim    CONF_MODULE *tmod;
312280304Sjkim    int i, nchar;
313280304Sjkim    char *p;
314280304Sjkim    p = strrchr(name, '.');
315109998Smarkm
316280304Sjkim    if (p)
317280304Sjkim        nchar = p - name;
318280304Sjkim    else
319280304Sjkim        nchar = strlen(name);
320109998Smarkm
321280304Sjkim    for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) {
322280304Sjkim        tmod = sk_CONF_MODULE_value(supported_modules, i);
323280304Sjkim        if (!strncmp(tmod->name, name, nchar))
324280304Sjkim            return tmod;
325280304Sjkim    }
326109998Smarkm
327280304Sjkim    return NULL;
328109998Smarkm
329280304Sjkim}
330109998Smarkm
331109998Smarkm/* initialize a module */
332109998Smarkmstatic int module_init(CONF_MODULE *pmod, char *name, char *value,
333280304Sjkim                       const CONF *cnf)
334280304Sjkim{
335280304Sjkim    int ret = 1;
336280304Sjkim    int init_called = 0;
337280304Sjkim    CONF_IMODULE *imod = NULL;
338109998Smarkm
339280304Sjkim    /* Otherwise add initialized module to list */
340280304Sjkim    imod = OPENSSL_malloc(sizeof(CONF_IMODULE));
341280304Sjkim    if (!imod)
342280304Sjkim        goto err;
343109998Smarkm
344280304Sjkim    imod->pmod = pmod;
345280304Sjkim    imod->name = BUF_strdup(name);
346280304Sjkim    imod->value = BUF_strdup(value);
347280304Sjkim    imod->usr_data = NULL;
348109998Smarkm
349280304Sjkim    if (!imod->name || !imod->value)
350280304Sjkim        goto memerr;
351109998Smarkm
352280304Sjkim    /* Try to initialize module */
353280304Sjkim    if (pmod->init) {
354280304Sjkim        ret = pmod->init(imod, cnf);
355280304Sjkim        init_called = 1;
356280304Sjkim        /* Error occurred, exit */
357280304Sjkim        if (ret <= 0)
358280304Sjkim            goto err;
359280304Sjkim    }
360109998Smarkm
361280304Sjkim    if (initialized_modules == NULL) {
362280304Sjkim        initialized_modules = sk_CONF_IMODULE_new_null();
363280304Sjkim        if (!initialized_modules) {
364280304Sjkim            CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
365280304Sjkim            goto err;
366280304Sjkim        }
367280304Sjkim    }
368109998Smarkm
369280304Sjkim    if (!sk_CONF_IMODULE_push(initialized_modules, imod)) {
370280304Sjkim        CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
371280304Sjkim        goto err;
372280304Sjkim    }
373109998Smarkm
374280304Sjkim    pmod->links++;
375109998Smarkm
376280304Sjkim    return ret;
377109998Smarkm
378280304Sjkim err:
379109998Smarkm
380280304Sjkim    /* We've started the module so we'd better finish it */
381280304Sjkim    if (pmod->finish && init_called)
382280304Sjkim        pmod->finish(imod);
383109998Smarkm
384280304Sjkim memerr:
385280304Sjkim    if (imod) {
386280304Sjkim        if (imod->name)
387280304Sjkim            OPENSSL_free(imod->name);
388280304Sjkim        if (imod->value)
389280304Sjkim            OPENSSL_free(imod->value);
390280304Sjkim        OPENSSL_free(imod);
391280304Sjkim    }
392109998Smarkm
393280304Sjkim    return -1;
394109998Smarkm
395280304Sjkim}
396109998Smarkm
397280304Sjkim/*
398280304Sjkim * Unload any dynamic modules that have a link count of zero: i.e. have no
399280304Sjkim * active initialized modules. If 'all' is set then all modules are unloaded
400280304Sjkim * including static ones.
401109998Smarkm */
402109998Smarkm
403109998Smarkmvoid CONF_modules_unload(int all)
404280304Sjkim{
405280304Sjkim    int i;
406280304Sjkim    CONF_MODULE *md;
407280304Sjkim    CONF_modules_finish();
408280304Sjkim    /* unload modules in reverse order */
409280304Sjkim    for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) {
410280304Sjkim        md = sk_CONF_MODULE_value(supported_modules, i);
411280304Sjkim        /* If static or in use and 'all' not set ignore it */
412280304Sjkim        if (((md->links > 0) || !md->dso) && !all)
413280304Sjkim            continue;
414280304Sjkim        /* Since we're working in reverse this is OK */
415280304Sjkim        (void)sk_CONF_MODULE_delete(supported_modules, i);
416280304Sjkim        module_free(md);
417280304Sjkim    }
418280304Sjkim    if (sk_CONF_MODULE_num(supported_modules) == 0) {
419280304Sjkim        sk_CONF_MODULE_free(supported_modules);
420280304Sjkim        supported_modules = NULL;
421280304Sjkim    }
422280304Sjkim}
423109998Smarkm
424109998Smarkm/* unload a single module */
425109998Smarkmstatic void module_free(CONF_MODULE *md)
426280304Sjkim{
427280304Sjkim    if (md->dso)
428280304Sjkim        DSO_free(md->dso);
429280304Sjkim    OPENSSL_free(md->name);
430280304Sjkim    OPENSSL_free(md);
431280304Sjkim}
432109998Smarkm
433109998Smarkm/* finish and free up all modules instances */
434109998Smarkm
435109998Smarkmvoid CONF_modules_finish(void)
436280304Sjkim{
437280304Sjkim    CONF_IMODULE *imod;
438280304Sjkim    while (sk_CONF_IMODULE_num(initialized_modules) > 0) {
439280304Sjkim        imod = sk_CONF_IMODULE_pop(initialized_modules);
440280304Sjkim        module_finish(imod);
441280304Sjkim    }
442280304Sjkim    sk_CONF_IMODULE_free(initialized_modules);
443280304Sjkim    initialized_modules = NULL;
444280304Sjkim}
445109998Smarkm
446109998Smarkm/* finish a module instance */
447109998Smarkm
448109998Smarkmstatic void module_finish(CONF_IMODULE *imod)
449280304Sjkim{
450280304Sjkim    if (imod->pmod->finish)
451280304Sjkim        imod->pmod->finish(imod);
452280304Sjkim    imod->pmod->links--;
453280304Sjkim    OPENSSL_free(imod->name);
454280304Sjkim    OPENSSL_free(imod->value);
455280304Sjkim    OPENSSL_free(imod);
456280304Sjkim}
457109998Smarkm
458109998Smarkm/* Add a static module to OpenSSL */
459109998Smarkm
460280304Sjkimint CONF_module_add(const char *name, conf_init_func *ifunc,
461280304Sjkim                    conf_finish_func *ffunc)
462280304Sjkim{
463280304Sjkim    if (module_add(NULL, name, ifunc, ffunc))
464280304Sjkim        return 1;
465280304Sjkim    else
466280304Sjkim        return 0;
467280304Sjkim}
468109998Smarkm
469109998Smarkmvoid CONF_modules_free(void)
470280304Sjkim{
471280304Sjkim    CONF_modules_finish();
472280304Sjkim    CONF_modules_unload(1);
473280304Sjkim}
474109998Smarkm
475109998Smarkm/* Utility functions */
476109998Smarkm
477109998Smarkmconst char *CONF_imodule_get_name(const CONF_IMODULE *md)
478280304Sjkim{
479280304Sjkim    return md->name;
480280304Sjkim}
481109998Smarkm
482109998Smarkmconst char *CONF_imodule_get_value(const CONF_IMODULE *md)
483280304Sjkim{
484280304Sjkim    return md->value;
485280304Sjkim}
486109998Smarkm
487109998Smarkmvoid *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
488280304Sjkim{
489280304Sjkim    return md->usr_data;
490280304Sjkim}
491109998Smarkm
492109998Smarkmvoid CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
493280304Sjkim{
494280304Sjkim    md->usr_data = usr_data;
495280304Sjkim}
496109998Smarkm
497109998SmarkmCONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
498280304Sjkim{
499280304Sjkim    return md->pmod;
500280304Sjkim}
501109998Smarkm
502109998Smarkmunsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
503280304Sjkim{
504280304Sjkim    return md->flags;
505280304Sjkim}
506109998Smarkm
507109998Smarkmvoid CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
508280304Sjkim{
509280304Sjkim    md->flags = flags;
510280304Sjkim}
511109998Smarkm
512109998Smarkmvoid *CONF_module_get_usr_data(CONF_MODULE *pmod)
513280304Sjkim{
514280304Sjkim    return pmod->usr_data;
515280304Sjkim}
516109998Smarkm
517109998Smarkmvoid CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
518280304Sjkim{
519280304Sjkim    pmod->usr_data = usr_data;
520280304Sjkim}
521109998Smarkm
522109998Smarkm/* Return default config file name */
523109998Smarkm
524109998Smarkmchar *CONF_get1_default_config_file(void)
525280304Sjkim{
526280304Sjkim    char *file;
527280304Sjkim    int len;
528109998Smarkm
529280304Sjkim    file = getenv("OPENSSL_CONF");
530280304Sjkim    if (file)
531280304Sjkim        return BUF_strdup(file);
532109998Smarkm
533280304Sjkim    len = strlen(X509_get_default_cert_area());
534109998Smarkm#ifndef OPENSSL_SYS_VMS
535280304Sjkim    len++;
536109998Smarkm#endif
537280304Sjkim    len += strlen(OPENSSL_CONF);
538109998Smarkm
539280304Sjkim    file = OPENSSL_malloc(len + 1);
540109998Smarkm
541280304Sjkim    if (!file)
542280304Sjkim        return NULL;
543280304Sjkim    BUF_strlcpy(file, X509_get_default_cert_area(), len + 1);
544109998Smarkm#ifndef OPENSSL_SYS_VMS
545280304Sjkim    BUF_strlcat(file, "/", len + 1);
546109998Smarkm#endif
547280304Sjkim    BUF_strlcat(file, OPENSSL_CONF, len + 1);
548109998Smarkm
549280304Sjkim    return file;
550280304Sjkim}
551109998Smarkm
552280304Sjkim/*
553280304Sjkim * This function takes a list separated by 'sep' and calls the callback
554280304Sjkim * function giving the start and length of each member optionally stripping
555280304Sjkim * leading and trailing whitespace. This can be used to parse comma separated
556280304Sjkim * lists for example.
557109998Smarkm */
558109998Smarkm
559127128Snectarint CONF_parse_list(const char *list_, int sep, int nospc,
560280304Sjkim                    int (*list_cb) (const char *elem, int len, void *usr),
561280304Sjkim                    void *arg)
562280304Sjkim{
563280304Sjkim    int ret;
564280304Sjkim    const char *lstart, *tmpend, *p;
565238405Sjkim
566280304Sjkim    if (list_ == NULL) {
567280304Sjkim        CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
568280304Sjkim        return 0;
569280304Sjkim    }
570238405Sjkim
571280304Sjkim    lstart = list_;
572280304Sjkim    for (;;) {
573280304Sjkim        if (nospc) {
574280304Sjkim            while (*lstart && isspace((unsigned char)*lstart))
575280304Sjkim                lstart++;
576280304Sjkim        }
577280304Sjkim        p = strchr(lstart, sep);
578280304Sjkim        if (p == lstart || !*lstart)
579280304Sjkim            ret = list_cb(NULL, 0, arg);
580280304Sjkim        else {
581280304Sjkim            if (p)
582280304Sjkim                tmpend = p - 1;
583280304Sjkim            else
584280304Sjkim                tmpend = lstart + strlen(lstart) - 1;
585280304Sjkim            if (nospc) {
586280304Sjkim                while (isspace((unsigned char)*tmpend))
587280304Sjkim                    tmpend--;
588280304Sjkim            }
589280304Sjkim            ret = list_cb(lstart, tmpend - lstart + 1, arg);
590280304Sjkim        }
591280304Sjkim        if (ret <= 0)
592280304Sjkim            return ret;
593280304Sjkim        if (p == NULL)
594280304Sjkim            return 1;
595280304Sjkim        lstart = p + 1;
596280304Sjkim    }
597280304Sjkim}
598