10Sstevel@tonic-gate /* conf_mod.c */
20Sstevel@tonic-gate /* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
30Sstevel@tonic-gate * project 2001.
40Sstevel@tonic-gate */
50Sstevel@tonic-gate /* ====================================================================
60Sstevel@tonic-gate * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
90Sstevel@tonic-gate * modification, are permitted provided that the following conditions
100Sstevel@tonic-gate * are met:
110Sstevel@tonic-gate *
120Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
130Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
140Sstevel@tonic-gate *
150Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
160Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
170Sstevel@tonic-gate * the documentation and/or other materials provided with the
180Sstevel@tonic-gate * distribution.
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
210Sstevel@tonic-gate * software must display the following acknowledgment:
220Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
230Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
240Sstevel@tonic-gate *
250Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
260Sstevel@tonic-gate * endorse or promote products derived from this software without
270Sstevel@tonic-gate * prior written permission. For written permission, please contact
280Sstevel@tonic-gate * licensing@OpenSSL.org.
290Sstevel@tonic-gate *
300Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
310Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
320Sstevel@tonic-gate * permission of the OpenSSL Project.
330Sstevel@tonic-gate *
340Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
350Sstevel@tonic-gate * acknowledgment:
360Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
370Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
380Sstevel@tonic-gate *
390Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
400Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
420Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
430Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
440Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
460Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
470Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
480Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
490Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
500Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
510Sstevel@tonic-gate * ====================================================================
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
540Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
550Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
560Sstevel@tonic-gate *
570Sstevel@tonic-gate */
580Sstevel@tonic-gate
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include <ctype.h>
610Sstevel@tonic-gate #include <openssl/crypto.h>
620Sstevel@tonic-gate #include "cryptlib.h"
630Sstevel@tonic-gate #include <openssl/conf.h>
640Sstevel@tonic-gate #include <openssl/dso.h>
650Sstevel@tonic-gate #include <openssl/x509.h>
660Sstevel@tonic-gate
670Sstevel@tonic-gate
680Sstevel@tonic-gate #define DSO_mod_init_name "OPENSSL_init"
690Sstevel@tonic-gate #define DSO_mod_finish_name "OPENSSL_finish"
700Sstevel@tonic-gate
710Sstevel@tonic-gate
720Sstevel@tonic-gate /* This structure contains a data about supported modules.
730Sstevel@tonic-gate * entries in this table correspond to either dynamic or
740Sstevel@tonic-gate * static modules.
750Sstevel@tonic-gate */
760Sstevel@tonic-gate
770Sstevel@tonic-gate struct conf_module_st
780Sstevel@tonic-gate {
790Sstevel@tonic-gate /* DSO of this module or NULL if static */
800Sstevel@tonic-gate DSO *dso;
810Sstevel@tonic-gate /* Name of the module */
820Sstevel@tonic-gate char *name;
830Sstevel@tonic-gate /* Init function */
840Sstevel@tonic-gate conf_init_func *init;
850Sstevel@tonic-gate /* Finish function */
860Sstevel@tonic-gate conf_finish_func *finish;
870Sstevel@tonic-gate /* Number of successfully initialized modules */
880Sstevel@tonic-gate int links;
890Sstevel@tonic-gate void *usr_data;
900Sstevel@tonic-gate };
910Sstevel@tonic-gate
920Sstevel@tonic-gate
930Sstevel@tonic-gate /* This structure contains information about modules that have been
940Sstevel@tonic-gate * successfully initialized. There may be more than one entry for a
950Sstevel@tonic-gate * given module.
960Sstevel@tonic-gate */
970Sstevel@tonic-gate
980Sstevel@tonic-gate struct conf_imodule_st
990Sstevel@tonic-gate {
1000Sstevel@tonic-gate CONF_MODULE *pmod;
1010Sstevel@tonic-gate char *name;
1020Sstevel@tonic-gate char *value;
1030Sstevel@tonic-gate unsigned long flags;
1040Sstevel@tonic-gate void *usr_data;
1050Sstevel@tonic-gate };
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate static STACK_OF(CONF_MODULE) *supported_modules = NULL;
1080Sstevel@tonic-gate static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate static void module_free(CONF_MODULE *md);
1110Sstevel@tonic-gate static void module_finish(CONF_IMODULE *imod);
1120Sstevel@tonic-gate static int module_run(const CONF *cnf, char *name, char *value,
1130Sstevel@tonic-gate unsigned long flags);
1140Sstevel@tonic-gate static CONF_MODULE *module_add(DSO *dso, const char *name,
1150Sstevel@tonic-gate conf_init_func *ifunc, conf_finish_func *ffunc);
1160Sstevel@tonic-gate static CONF_MODULE *module_find(char *name);
1170Sstevel@tonic-gate static int module_init(CONF_MODULE *pmod, char *name, char *value,
1180Sstevel@tonic-gate const CONF *cnf);
1190Sstevel@tonic-gate static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
1200Sstevel@tonic-gate unsigned long flags);
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate /* Main function: load modules from a CONF structure */
1230Sstevel@tonic-gate
CONF_modules_load(const CONF * cnf,const char * appname,unsigned long flags)1240Sstevel@tonic-gate int CONF_modules_load(const CONF *cnf, const char *appname,
1250Sstevel@tonic-gate unsigned long flags)
1260Sstevel@tonic-gate {
1270Sstevel@tonic-gate STACK_OF(CONF_VALUE) *values;
1280Sstevel@tonic-gate CONF_VALUE *vl;
1290Sstevel@tonic-gate char *vsection;
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate int ret, i;
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate if (!cnf)
1340Sstevel@tonic-gate return 1;
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate if (appname == NULL)
1370Sstevel@tonic-gate appname = "openssl_conf";
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate vsection = NCONF_get_string(cnf, NULL, appname);
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate if (!vsection)
1420Sstevel@tonic-gate {
1430Sstevel@tonic-gate ERR_clear_error();
1440Sstevel@tonic-gate return 1;
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate values = NCONF_get_section(cnf, vsection);
1480Sstevel@tonic-gate
1490Sstevel@tonic-gate if (!values)
1500Sstevel@tonic-gate return 0;
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate for (i = 0; i < sk_CONF_VALUE_num(values); i++)
1530Sstevel@tonic-gate {
1540Sstevel@tonic-gate vl = sk_CONF_VALUE_value(values, i);
1550Sstevel@tonic-gate ret = module_run(cnf, vl->name, vl->value, flags);
1560Sstevel@tonic-gate if (ret <= 0)
1570Sstevel@tonic-gate if(!(flags & CONF_MFLAGS_IGNORE_ERRORS))
1580Sstevel@tonic-gate return ret;
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate return 1;
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate }
1640Sstevel@tonic-gate
CONF_modules_load_file(const char * filename,const char * appname,unsigned long flags)1650Sstevel@tonic-gate int CONF_modules_load_file(const char *filename, const char *appname,
1660Sstevel@tonic-gate unsigned long flags)
1670Sstevel@tonic-gate {
1680Sstevel@tonic-gate char *file = NULL;
1690Sstevel@tonic-gate CONF *conf = NULL;
1700Sstevel@tonic-gate int ret = 0;
1710Sstevel@tonic-gate conf = NCONF_new(NULL);
1720Sstevel@tonic-gate if (!conf)
1730Sstevel@tonic-gate goto err;
1740Sstevel@tonic-gate
1750Sstevel@tonic-gate if (filename == NULL)
1760Sstevel@tonic-gate {
1770Sstevel@tonic-gate file = CONF_get1_default_config_file();
1780Sstevel@tonic-gate if (!file)
1790Sstevel@tonic-gate goto err;
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate else
1820Sstevel@tonic-gate file = (char *)filename;
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate if (NCONF_load(conf, file, NULL) <= 0)
1850Sstevel@tonic-gate {
1860Sstevel@tonic-gate if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
1870Sstevel@tonic-gate (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE))
1880Sstevel@tonic-gate {
1890Sstevel@tonic-gate ERR_clear_error();
1900Sstevel@tonic-gate ret = 1;
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate goto err;
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate ret = CONF_modules_load(conf, appname, flags);
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate err:
1980Sstevel@tonic-gate if (filename == NULL)
1990Sstevel@tonic-gate OPENSSL_free(file);
2000Sstevel@tonic-gate NCONF_free(conf);
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate return ret;
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate
module_run(const CONF * cnf,char * name,char * value,unsigned long flags)2050Sstevel@tonic-gate static int module_run(const CONF *cnf, char *name, char *value,
2060Sstevel@tonic-gate unsigned long flags)
2070Sstevel@tonic-gate {
2080Sstevel@tonic-gate CONF_MODULE *md;
2090Sstevel@tonic-gate int ret;
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate md = module_find(name);
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate /* Module not found: try to load DSO */
2140Sstevel@tonic-gate if (!md && !(flags & CONF_MFLAGS_NO_DSO))
2150Sstevel@tonic-gate md = module_load_dso(cnf, name, value, flags);
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate if (!md)
2180Sstevel@tonic-gate {
2190Sstevel@tonic-gate if (!(flags & CONF_MFLAGS_SILENT))
2200Sstevel@tonic-gate {
2210Sstevel@tonic-gate CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);
2220Sstevel@tonic-gate ERR_add_error_data(2, "module=", name);
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate return -1;
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate
2270Sstevel@tonic-gate ret = module_init(md, name, value, cnf);
2280Sstevel@tonic-gate
2290Sstevel@tonic-gate if (ret <= 0)
2300Sstevel@tonic-gate {
2310Sstevel@tonic-gate if (!(flags & CONF_MFLAGS_SILENT))
2320Sstevel@tonic-gate {
2330Sstevel@tonic-gate char rcode[DECIMAL_SIZE(ret)+1];
234*2139Sjp161948 CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);
2350Sstevel@tonic-gate BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);
2360Sstevel@tonic-gate ERR_add_error_data(6, "module=", name, ", value=", value, ", retcode=", rcode);
2370Sstevel@tonic-gate }
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate
2400Sstevel@tonic-gate return ret;
2410Sstevel@tonic-gate }
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate /* Load a module from a DSO */
module_load_dso(const CONF * cnf,char * name,char * value,unsigned long flags)2440Sstevel@tonic-gate static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
2450Sstevel@tonic-gate unsigned long flags)
2460Sstevel@tonic-gate {
2470Sstevel@tonic-gate DSO *dso = NULL;
2480Sstevel@tonic-gate conf_init_func *ifunc;
2490Sstevel@tonic-gate conf_finish_func *ffunc;
2500Sstevel@tonic-gate char *path = NULL;
2510Sstevel@tonic-gate int errcode = 0;
2520Sstevel@tonic-gate CONF_MODULE *md;
2530Sstevel@tonic-gate /* Look for alternative path in module section */
2540Sstevel@tonic-gate path = NCONF_get_string(cnf, value, "path");
2550Sstevel@tonic-gate if (!path)
2560Sstevel@tonic-gate {
257*2139Sjp161948 ERR_clear_error();
2580Sstevel@tonic-gate path = name;
2590Sstevel@tonic-gate }
2600Sstevel@tonic-gate dso = DSO_load(NULL, path, NULL, 0);
2610Sstevel@tonic-gate if (!dso)
2620Sstevel@tonic-gate {
2630Sstevel@tonic-gate errcode = CONF_R_ERROR_LOADING_DSO;
2640Sstevel@tonic-gate goto err;
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
2670Sstevel@tonic-gate if (!ifunc)
2680Sstevel@tonic-gate {
2690Sstevel@tonic-gate errcode = CONF_R_MISSING_INIT_FUNCTION;
2700Sstevel@tonic-gate goto err;
2710Sstevel@tonic-gate }
2720Sstevel@tonic-gate ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
2730Sstevel@tonic-gate /* All OK, add module */
2740Sstevel@tonic-gate md = module_add(dso, name, ifunc, ffunc);
2750Sstevel@tonic-gate
2760Sstevel@tonic-gate if (!md)
2770Sstevel@tonic-gate goto err;
2780Sstevel@tonic-gate
2790Sstevel@tonic-gate return md;
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate err:
2820Sstevel@tonic-gate if (dso)
2830Sstevel@tonic-gate DSO_free(dso);
2840Sstevel@tonic-gate CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);
2850Sstevel@tonic-gate ERR_add_error_data(4, "module=", name, ", path=", path);
2860Sstevel@tonic-gate return NULL;
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate /* add module to list */
module_add(DSO * dso,const char * name,conf_init_func * ifunc,conf_finish_func * ffunc)2900Sstevel@tonic-gate static CONF_MODULE *module_add(DSO *dso, const char *name,
2910Sstevel@tonic-gate conf_init_func *ifunc, conf_finish_func *ffunc)
2920Sstevel@tonic-gate {
2930Sstevel@tonic-gate CONF_MODULE *tmod = NULL;
2940Sstevel@tonic-gate if (supported_modules == NULL)
2950Sstevel@tonic-gate supported_modules = sk_CONF_MODULE_new_null();
2960Sstevel@tonic-gate if (supported_modules == NULL)
2970Sstevel@tonic-gate return NULL;
2980Sstevel@tonic-gate tmod = OPENSSL_malloc(sizeof(CONF_MODULE));
2990Sstevel@tonic-gate if (tmod == NULL)
3000Sstevel@tonic-gate return NULL;
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate tmod->dso = dso;
3030Sstevel@tonic-gate tmod->name = BUF_strdup(name);
3040Sstevel@tonic-gate tmod->init = ifunc;
3050Sstevel@tonic-gate tmod->finish = ffunc;
3060Sstevel@tonic-gate tmod->links = 0;
3070Sstevel@tonic-gate
3080Sstevel@tonic-gate if (!sk_CONF_MODULE_push(supported_modules, tmod))
3090Sstevel@tonic-gate {
3100Sstevel@tonic-gate OPENSSL_free(tmod);
3110Sstevel@tonic-gate return NULL;
3120Sstevel@tonic-gate }
3130Sstevel@tonic-gate
3140Sstevel@tonic-gate return tmod;
3150Sstevel@tonic-gate }
3160Sstevel@tonic-gate
3170Sstevel@tonic-gate /* Find a module from the list. We allow module names of the
3180Sstevel@tonic-gate * form modname.XXXX to just search for modname to allow the
3190Sstevel@tonic-gate * same module to be initialized more than once.
3200Sstevel@tonic-gate */
3210Sstevel@tonic-gate
module_find(char * name)3220Sstevel@tonic-gate static CONF_MODULE *module_find(char *name)
3230Sstevel@tonic-gate {
3240Sstevel@tonic-gate CONF_MODULE *tmod;
3250Sstevel@tonic-gate int i, nchar;
3260Sstevel@tonic-gate char *p;
3270Sstevel@tonic-gate p = strrchr(name, '.');
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate if (p)
3300Sstevel@tonic-gate nchar = p - name;
3310Sstevel@tonic-gate else
3320Sstevel@tonic-gate nchar = strlen(name);
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++)
3350Sstevel@tonic-gate {
3360Sstevel@tonic-gate tmod = sk_CONF_MODULE_value(supported_modules, i);
3370Sstevel@tonic-gate if (!strncmp(tmod->name, name, nchar))
3380Sstevel@tonic-gate return tmod;
3390Sstevel@tonic-gate }
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate return NULL;
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate /* initialize a module */
module_init(CONF_MODULE * pmod,char * name,char * value,const CONF * cnf)3460Sstevel@tonic-gate static int module_init(CONF_MODULE *pmod, char *name, char *value,
3470Sstevel@tonic-gate const CONF *cnf)
3480Sstevel@tonic-gate {
3490Sstevel@tonic-gate int ret = 1;
3500Sstevel@tonic-gate int init_called = 0;
3510Sstevel@tonic-gate CONF_IMODULE *imod = NULL;
3520Sstevel@tonic-gate
3530Sstevel@tonic-gate /* Otherwise add initialized module to list */
3540Sstevel@tonic-gate imod = OPENSSL_malloc(sizeof(CONF_IMODULE));
3550Sstevel@tonic-gate if (!imod)
3560Sstevel@tonic-gate goto err;
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate imod->pmod = pmod;
3590Sstevel@tonic-gate imod->name = BUF_strdup(name);
3600Sstevel@tonic-gate imod->value = BUF_strdup(value);
3610Sstevel@tonic-gate imod->usr_data = NULL;
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate if (!imod->name || !imod->value)
3640Sstevel@tonic-gate goto memerr;
3650Sstevel@tonic-gate
3660Sstevel@tonic-gate /* Try to initialize module */
3670Sstevel@tonic-gate if(pmod->init)
3680Sstevel@tonic-gate {
3690Sstevel@tonic-gate ret = pmod->init(imod, cnf);
3700Sstevel@tonic-gate init_called = 1;
3710Sstevel@tonic-gate /* Error occurred, exit */
3720Sstevel@tonic-gate if (ret <= 0)
3730Sstevel@tonic-gate goto err;
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate if (initialized_modules == NULL)
3770Sstevel@tonic-gate {
3780Sstevel@tonic-gate initialized_modules = sk_CONF_IMODULE_new_null();
3790Sstevel@tonic-gate if (!initialized_modules)
3800Sstevel@tonic-gate {
3810Sstevel@tonic-gate CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
3820Sstevel@tonic-gate goto err;
3830Sstevel@tonic-gate }
3840Sstevel@tonic-gate }
3850Sstevel@tonic-gate
3860Sstevel@tonic-gate if (!sk_CONF_IMODULE_push(initialized_modules, imod))
3870Sstevel@tonic-gate {
3880Sstevel@tonic-gate CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
3890Sstevel@tonic-gate goto err;
3900Sstevel@tonic-gate }
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate pmod->links++;
3930Sstevel@tonic-gate
3940Sstevel@tonic-gate return ret;
3950Sstevel@tonic-gate
3960Sstevel@tonic-gate err:
3970Sstevel@tonic-gate
3980Sstevel@tonic-gate /* We've started the module so we'd better finish it */
3990Sstevel@tonic-gate if (pmod->finish && init_called)
4000Sstevel@tonic-gate pmod->finish(imod);
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate memerr:
4030Sstevel@tonic-gate if (imod)
4040Sstevel@tonic-gate {
4050Sstevel@tonic-gate if (imod->name)
4060Sstevel@tonic-gate OPENSSL_free(imod->name);
4070Sstevel@tonic-gate if (imod->value)
4080Sstevel@tonic-gate OPENSSL_free(imod->value);
4090Sstevel@tonic-gate OPENSSL_free(imod);
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate return -1;
4130Sstevel@tonic-gate
4140Sstevel@tonic-gate }
4150Sstevel@tonic-gate
4160Sstevel@tonic-gate /* Unload any dynamic modules that have a link count of zero:
4170Sstevel@tonic-gate * i.e. have no active initialized modules. If 'all' is set
4180Sstevel@tonic-gate * then all modules are unloaded including static ones.
4190Sstevel@tonic-gate */
4200Sstevel@tonic-gate
CONF_modules_unload(int all)4210Sstevel@tonic-gate void CONF_modules_unload(int all)
4220Sstevel@tonic-gate {
4230Sstevel@tonic-gate int i;
4240Sstevel@tonic-gate CONF_MODULE *md;
4250Sstevel@tonic-gate CONF_modules_finish();
4260Sstevel@tonic-gate /* unload modules in reverse order */
4270Sstevel@tonic-gate for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--)
4280Sstevel@tonic-gate {
4290Sstevel@tonic-gate md = sk_CONF_MODULE_value(supported_modules, i);
4300Sstevel@tonic-gate /* If static or in use and 'all' not set ignore it */
4310Sstevel@tonic-gate if (((md->links > 0) || !md->dso) && !all)
4320Sstevel@tonic-gate continue;
4330Sstevel@tonic-gate /* Since we're working in reverse this is OK */
4340Sstevel@tonic-gate sk_CONF_MODULE_delete(supported_modules, i);
4350Sstevel@tonic-gate module_free(md);
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate if (sk_CONF_MODULE_num(supported_modules) == 0)
4380Sstevel@tonic-gate {
4390Sstevel@tonic-gate sk_CONF_MODULE_free(supported_modules);
4400Sstevel@tonic-gate supported_modules = NULL;
4410Sstevel@tonic-gate }
4420Sstevel@tonic-gate }
4430Sstevel@tonic-gate
4440Sstevel@tonic-gate /* unload a single module */
module_free(CONF_MODULE * md)4450Sstevel@tonic-gate static void module_free(CONF_MODULE *md)
4460Sstevel@tonic-gate {
4470Sstevel@tonic-gate if (md->dso)
4480Sstevel@tonic-gate DSO_free(md->dso);
4490Sstevel@tonic-gate OPENSSL_free(md->name);
4500Sstevel@tonic-gate OPENSSL_free(md);
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate
4530Sstevel@tonic-gate /* finish and free up all modules instances */
4540Sstevel@tonic-gate
CONF_modules_finish(void)4550Sstevel@tonic-gate void CONF_modules_finish(void)
4560Sstevel@tonic-gate {
4570Sstevel@tonic-gate CONF_IMODULE *imod;
4580Sstevel@tonic-gate while (sk_CONF_IMODULE_num(initialized_modules) > 0)
4590Sstevel@tonic-gate {
4600Sstevel@tonic-gate imod = sk_CONF_IMODULE_pop(initialized_modules);
4610Sstevel@tonic-gate module_finish(imod);
4620Sstevel@tonic-gate }
4630Sstevel@tonic-gate sk_CONF_IMODULE_free(initialized_modules);
4640Sstevel@tonic-gate initialized_modules = NULL;
4650Sstevel@tonic-gate }
4660Sstevel@tonic-gate
4670Sstevel@tonic-gate /* finish a module instance */
4680Sstevel@tonic-gate
module_finish(CONF_IMODULE * imod)4690Sstevel@tonic-gate static void module_finish(CONF_IMODULE *imod)
4700Sstevel@tonic-gate {
4710Sstevel@tonic-gate if (imod->pmod->finish)
4720Sstevel@tonic-gate imod->pmod->finish(imod);
4730Sstevel@tonic-gate imod->pmod->links--;
4740Sstevel@tonic-gate OPENSSL_free(imod->name);
4750Sstevel@tonic-gate OPENSSL_free(imod->value);
4760Sstevel@tonic-gate OPENSSL_free(imod);
4770Sstevel@tonic-gate }
4780Sstevel@tonic-gate
4790Sstevel@tonic-gate /* Add a static module to OpenSSL */
4800Sstevel@tonic-gate
CONF_module_add(const char * name,conf_init_func * ifunc,conf_finish_func * ffunc)4810Sstevel@tonic-gate int CONF_module_add(const char *name, conf_init_func *ifunc,
4820Sstevel@tonic-gate conf_finish_func *ffunc)
4830Sstevel@tonic-gate {
4840Sstevel@tonic-gate if (module_add(NULL, name, ifunc, ffunc))
4850Sstevel@tonic-gate return 1;
4860Sstevel@tonic-gate else
4870Sstevel@tonic-gate return 0;
4880Sstevel@tonic-gate }
4890Sstevel@tonic-gate
CONF_modules_free(void)4900Sstevel@tonic-gate void CONF_modules_free(void)
4910Sstevel@tonic-gate {
4920Sstevel@tonic-gate CONF_modules_finish();
4930Sstevel@tonic-gate CONF_modules_unload(1);
4940Sstevel@tonic-gate }
4950Sstevel@tonic-gate
4960Sstevel@tonic-gate /* Utility functions */
4970Sstevel@tonic-gate
CONF_imodule_get_name(const CONF_IMODULE * md)4980Sstevel@tonic-gate const char *CONF_imodule_get_name(const CONF_IMODULE *md)
4990Sstevel@tonic-gate {
5000Sstevel@tonic-gate return md->name;
5010Sstevel@tonic-gate }
5020Sstevel@tonic-gate
CONF_imodule_get_value(const CONF_IMODULE * md)5030Sstevel@tonic-gate const char *CONF_imodule_get_value(const CONF_IMODULE *md)
5040Sstevel@tonic-gate {
5050Sstevel@tonic-gate return md->value;
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate
CONF_imodule_get_usr_data(const CONF_IMODULE * md)5080Sstevel@tonic-gate void *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
5090Sstevel@tonic-gate {
5100Sstevel@tonic-gate return md->usr_data;
5110Sstevel@tonic-gate }
5120Sstevel@tonic-gate
CONF_imodule_set_usr_data(CONF_IMODULE * md,void * usr_data)5130Sstevel@tonic-gate void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
5140Sstevel@tonic-gate {
5150Sstevel@tonic-gate md->usr_data = usr_data;
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate
CONF_imodule_get_module(const CONF_IMODULE * md)5180Sstevel@tonic-gate CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
5190Sstevel@tonic-gate {
5200Sstevel@tonic-gate return md->pmod;
5210Sstevel@tonic-gate }
5220Sstevel@tonic-gate
CONF_imodule_get_flags(const CONF_IMODULE * md)5230Sstevel@tonic-gate unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
5240Sstevel@tonic-gate {
5250Sstevel@tonic-gate return md->flags;
5260Sstevel@tonic-gate }
5270Sstevel@tonic-gate
CONF_imodule_set_flags(CONF_IMODULE * md,unsigned long flags)5280Sstevel@tonic-gate void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
5290Sstevel@tonic-gate {
5300Sstevel@tonic-gate md->flags = flags;
5310Sstevel@tonic-gate }
5320Sstevel@tonic-gate
CONF_module_get_usr_data(CONF_MODULE * pmod)5330Sstevel@tonic-gate void *CONF_module_get_usr_data(CONF_MODULE *pmod)
5340Sstevel@tonic-gate {
5350Sstevel@tonic-gate return pmod->usr_data;
5360Sstevel@tonic-gate }
5370Sstevel@tonic-gate
CONF_module_set_usr_data(CONF_MODULE * pmod,void * usr_data)5380Sstevel@tonic-gate void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
5390Sstevel@tonic-gate {
5400Sstevel@tonic-gate pmod->usr_data = usr_data;
5410Sstevel@tonic-gate }
5420Sstevel@tonic-gate
5430Sstevel@tonic-gate /* Return default config file name */
5440Sstevel@tonic-gate
CONF_get1_default_config_file(void)5450Sstevel@tonic-gate char *CONF_get1_default_config_file(void)
5460Sstevel@tonic-gate {
5470Sstevel@tonic-gate char *file;
5480Sstevel@tonic-gate int len;
5490Sstevel@tonic-gate
5500Sstevel@tonic-gate file = getenv("OPENSSL_CONF");
5510Sstevel@tonic-gate if (file)
5520Sstevel@tonic-gate return BUF_strdup(file);
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate len = strlen(X509_get_default_cert_area());
5550Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS
5560Sstevel@tonic-gate len++;
5570Sstevel@tonic-gate #endif
5580Sstevel@tonic-gate len += strlen(OPENSSL_CONF);
5590Sstevel@tonic-gate
5600Sstevel@tonic-gate file = OPENSSL_malloc(len + 1);
5610Sstevel@tonic-gate
5620Sstevel@tonic-gate if (!file)
5630Sstevel@tonic-gate return NULL;
5640Sstevel@tonic-gate BUF_strlcpy(file,X509_get_default_cert_area(),len + 1);
5650Sstevel@tonic-gate #ifndef OPENSSL_SYS_VMS
5660Sstevel@tonic-gate BUF_strlcat(file,"/",len + 1);
5670Sstevel@tonic-gate #endif
5680Sstevel@tonic-gate BUF_strlcat(file,OPENSSL_CONF,len + 1);
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate return file;
5710Sstevel@tonic-gate }
5720Sstevel@tonic-gate
5730Sstevel@tonic-gate /* This function takes a list separated by 'sep' and calls the
5740Sstevel@tonic-gate * callback function giving the start and length of each member
5750Sstevel@tonic-gate * optionally stripping leading and trailing whitespace. This can
5760Sstevel@tonic-gate * be used to parse comma separated lists for example.
5770Sstevel@tonic-gate */
5780Sstevel@tonic-gate
CONF_parse_list(const char * list_,int sep,int nospc,int (* list_cb)(const char * elem,int len,void * usr),void * arg)5790Sstevel@tonic-gate int CONF_parse_list(const char *list_, int sep, int nospc,
5800Sstevel@tonic-gate int (*list_cb)(const char *elem, int len, void *usr), void *arg)
5810Sstevel@tonic-gate {
5820Sstevel@tonic-gate int ret;
5830Sstevel@tonic-gate const char *lstart, *tmpend, *p;
5840Sstevel@tonic-gate lstart = list_;
5850Sstevel@tonic-gate
5860Sstevel@tonic-gate for(;;)
5870Sstevel@tonic-gate {
5880Sstevel@tonic-gate if (nospc)
5890Sstevel@tonic-gate {
5900Sstevel@tonic-gate while(*lstart && isspace((unsigned char)*lstart))
5910Sstevel@tonic-gate lstart++;
5920Sstevel@tonic-gate }
5930Sstevel@tonic-gate p = strchr(lstart, sep);
5940Sstevel@tonic-gate if (p == lstart || !*lstart)
5950Sstevel@tonic-gate ret = list_cb(NULL, 0, arg);
5960Sstevel@tonic-gate else
5970Sstevel@tonic-gate {
5980Sstevel@tonic-gate if (p)
5990Sstevel@tonic-gate tmpend = p - 1;
6000Sstevel@tonic-gate else
6010Sstevel@tonic-gate tmpend = lstart + strlen(lstart) - 1;
6020Sstevel@tonic-gate if (nospc)
6030Sstevel@tonic-gate {
6040Sstevel@tonic-gate while(isspace((unsigned char)*tmpend))
6050Sstevel@tonic-gate tmpend--;
6060Sstevel@tonic-gate }
6070Sstevel@tonic-gate ret = list_cb(lstart, tmpend - lstart + 1, arg);
6080Sstevel@tonic-gate }
6090Sstevel@tonic-gate if (ret <= 0)
6100Sstevel@tonic-gate return ret;
6110Sstevel@tonic-gate if (p == NULL)
6120Sstevel@tonic-gate return 1;
6130Sstevel@tonic-gate lstart = p + 1;
6140Sstevel@tonic-gate }
6150Sstevel@tonic-gate }
6160Sstevel@tonic-gate
617