xref: /onnv-gate/usr/src/common/openssl/crypto/conf/conf_mod.c (revision 2139:6243c3338933)
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