⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 conf_mod.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
字号:
/* conf_mod.c *//* Written by Stephen Henson (steve@openssl.org) for the OpenSSL * project 2001. *//* ==================================================================== * Copyright (c) 2001 The OpenSSL Project.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For written permission, please contact *    licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" *    nor may "OpenSSL" appear in their names without prior written *    permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com).  This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */#include <stdio.h>#include <ctype.h>#include <openssl/crypto.h>#include "cryptlib.h"#include <openssl/conf.h>#include <openssl/dso.h>#include <openssl/x509.h>#define DSO_mod_init_name "OPENSSL_init"#define DSO_mod_finish_name "OPENSSL_finish"/* This structure contains a data about supported modules. * entries in this table correspond to either dynamic or * static modules. */struct conf_module_st	{	/* DSO of this module or NULL if static */	DSO *dso;	/* Name of the module */	char *name;	/* Init function */	conf_init_func *init; 	/* Finish function */	conf_finish_func *finish;	/* Number of successfully initialized modules */	int links;	void *usr_data;	};/* This structure contains information about modules that have been * successfully initialized. There may be more than one entry for a * given module. */struct conf_imodule_st	{	CONF_MODULE *pmod;	char *name;	char *value;	unsigned long flags;	void *usr_data;	};static STACK_OF(CONF_MODULE) *supported_modules = NULL;static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;static void module_free(CONF_MODULE *md);static void module_finish(CONF_IMODULE *imod);static int module_run(const CONF *cnf, char *name, char *value,					  unsigned long flags);static CONF_MODULE *module_add(DSO *dso, const char *name,			conf_init_func *ifunc, conf_finish_func *ffunc);static CONF_MODULE *module_find(char *name);static int module_init(CONF_MODULE *pmod, char *name, char *value,					   const CONF *cnf);static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,									unsigned long flags);/* Main function: load modules from a CONF structure */int CONF_modules_load(const CONF *cnf, const char *appname,		      unsigned long flags)	{	STACK_OF(CONF_VALUE) *values;	CONF_VALUE *vl;	char *vsection = NULL;	int ret, i;	if (!cnf)		return 1;	if (appname)		vsection = NCONF_get_string(cnf, NULL, appname);	if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))		vsection = NCONF_get_string(cnf, NULL, "openssl_conf");	if (!vsection)		{		ERR_clear_error();		return 1;		}	values = NCONF_get_section(cnf, vsection);	if (!values)		return 0;	for (i = 0; i < sk_CONF_VALUE_num(values); i++)		{		vl = sk_CONF_VALUE_value(values, i);		ret = module_run(cnf, vl->name, vl->value, flags);		if (ret <= 0)			if(!(flags & CONF_MFLAGS_IGNORE_ERRORS))				return ret;		}	return 1;	}int CONF_modules_load_file(const char *filename, const char *appname,			   unsigned long flags)	{	char *file = NULL;	CONF *conf = NULL;	int ret = 0;	conf = NCONF_new(NULL);	if (!conf)		goto err;	if (filename == NULL)		{		file = CONF_get1_default_config_file();		if (!file)			goto err;		}	else		file = (char *)filename;	if (NCONF_load(conf, file, NULL) <= 0)		{		if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&		  (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE))			{			ERR_clear_error();			ret = 1;			}		goto err;		}	ret = CONF_modules_load(conf, appname, flags);	err:	if (filename == NULL)		OPENSSL_free(file);	NCONF_free(conf);	return ret;	}static int module_run(const CONF *cnf, char *name, char *value,		      unsigned long flags)	{	CONF_MODULE *md;	int ret;	md = module_find(name);	/* Module not found: try to load DSO */	if (!md && !(flags & CONF_MFLAGS_NO_DSO))		md = module_load_dso(cnf, name, value, flags);	if (!md)		{		if (!(flags & CONF_MFLAGS_SILENT))			{			CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);			ERR_add_error_data(2, "module=", name);			}		return -1;		}	ret = module_init(md, name, value, cnf);	if (ret <= 0)		{		if (!(flags & CONF_MFLAGS_SILENT))			{			char rcode[DECIMAL_SIZE(ret)+1];			CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);			BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);			ERR_add_error_data(6, "module=", name, ", value=", value, ", retcode=", rcode);			}		}	return ret;	}/* Load a module from a DSO */static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,				    unsigned long flags)	{	DSO *dso = NULL;	conf_init_func *ifunc;	conf_finish_func *ffunc;	char *path = NULL;	int errcode = 0;	CONF_MODULE *md;	/* Look for alternative path in module section */	path = NCONF_get_string(cnf, value, "path");	if (!path)		{		ERR_clear_error();		path = name;		}	dso = DSO_load(NULL, path, NULL, 0);	if (!dso)		{		errcode = CONF_R_ERROR_LOADING_DSO;		goto err;		}        ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);	if (!ifunc)		{		errcode = CONF_R_MISSING_INIT_FUNCTION;		goto err;		}        ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);	/* All OK, add module */	md = module_add(dso, name, ifunc, ffunc);	if (!md)		goto err;	return md;	err:	if (dso)		DSO_free(dso);	CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);	ERR_add_error_data(4, "module=", name, ", path=", path);	return NULL;	}/* add module to list */static CONF_MODULE *module_add(DSO *dso, const char *name,			       conf_init_func *ifunc, conf_finish_func *ffunc)	{	CONF_MODULE *tmod = NULL;	if (supported_modules == NULL)		supported_modules = sk_CONF_MODULE_new_null();	if (supported_modules == NULL)		return NULL;	tmod = OPENSSL_malloc(sizeof(CONF_MODULE));	if (tmod == NULL)		return NULL;	tmod->dso = dso;	tmod->name = BUF_strdup(name);	tmod->init = ifunc;	tmod->finish = ffunc;	tmod->links = 0;	if (!sk_CONF_MODULE_push(supported_modules, tmod))		{		OPENSSL_free(tmod);		return NULL;		}	return tmod;	}/* Find a module from the list. We allow module names of the * form modname.XXXX to just search for modname to allow the * same module to be initialized more than once. */static CONF_MODULE *module_find(char *name)	{	CONF_MODULE *tmod;	int i, nchar;	char *p;	p = strrchr(name, '.');	if (p)		nchar = p - name;	else 		nchar = strlen(name);	for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++)		{		tmod = sk_CONF_MODULE_value(supported_modules, i);		if (!strncmp(tmod->name, name, nchar))			return tmod;		}	return NULL;	}/* initialize a module */static int module_init(CONF_MODULE *pmod, char *name, char *value,		       const CONF *cnf)	{	int ret = 1;	int init_called = 0;	CONF_IMODULE *imod = NULL;	/* Otherwise add initialized module to list */	imod = OPENSSL_malloc(sizeof(CONF_IMODULE));	if (!imod)		goto err;	imod->pmod = pmod;	imod->name = BUF_strdup(name);	imod->value = BUF_strdup(value);	imod->usr_data = NULL;	if (!imod->name || !imod->value)		goto memerr;	/* Try to initialize module */	if(pmod->init)		{		ret = pmod->init(imod, cnf);		init_called = 1;		/* Error occurred, exit */		if (ret <= 0)			goto err;		}	if (initialized_modules == NULL)		{		initialized_modules = sk_CONF_IMODULE_new_null();		if (!initialized_modules)			{			CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);			goto err;			}		}	if (!sk_CONF_IMODULE_push(initialized_modules, imod))		{		CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);		goto err;		}	pmod->links++;	return ret;	err:	/* We've started the module so we'd better finish it */	if (pmod->finish && init_called)		pmod->finish(imod);	memerr:	if (imod)		{		if (imod->name)			OPENSSL_free(imod->name);		if (imod->value)			OPENSSL_free(imod->value);		OPENSSL_free(imod);		}	return -1;	}/* Unload any dynamic modules that have a link count of zero: * i.e. have no active initialized modules. If 'all' is set * then all modules are unloaded including static ones. */void CONF_modules_unload(int all)	{	int i;	CONF_MODULE *md;	CONF_modules_finish();	/* unload modules in reverse order */	for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--)		{		md = sk_CONF_MODULE_value(supported_modules, i);		/* If static or in use and 'all' not set ignore it */		if (((md->links > 0) || !md->dso) && !all)			continue;		/* Since we're working in reverse this is OK */		(void)sk_CONF_MODULE_delete(supported_modules, i);		module_free(md);		}	if (sk_CONF_MODULE_num(supported_modules) == 0)		{		sk_CONF_MODULE_free(supported_modules);		supported_modules = NULL;		}	}/* unload a single module */static void module_free(CONF_MODULE *md)	{	if (md->dso)		DSO_free(md->dso);	OPENSSL_free(md->name);	OPENSSL_free(md);	}/* finish and free up all modules instances */void CONF_modules_finish(void)	{	CONF_IMODULE *imod;	while (sk_CONF_IMODULE_num(initialized_modules) > 0)		{		imod = sk_CONF_IMODULE_pop(initialized_modules);		module_finish(imod);		}	sk_CONF_IMODULE_free(initialized_modules);	initialized_modules = NULL;	}/* finish a module instance */static void module_finish(CONF_IMODULE *imod)	{	if (imod->pmod->finish)		imod->pmod->finish(imod);	imod->pmod->links--;	OPENSSL_free(imod->name);	OPENSSL_free(imod->value);	OPENSSL_free(imod);	}/* Add a static module to OpenSSL */int CONF_module_add(const char *name, conf_init_func *ifunc, 		    conf_finish_func *ffunc)	{	if (module_add(NULL, name, ifunc, ffunc))		return 1;	else		return 0;	}void CONF_modules_free(void)	{	CONF_modules_finish();	CONF_modules_unload(1);	}/* Utility functions */const char *CONF_imodule_get_name(const CONF_IMODULE *md)	{	return md->name;	}const char *CONF_imodule_get_value(const CONF_IMODULE *md)	{	return md->value;	}void *CONF_imodule_get_usr_data(const CONF_IMODULE *md)	{	return md->usr_data;	}void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)	{	md->usr_data = usr_data;	}CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)	{	return md->pmod;	}unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)	{	return md->flags;	}void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)	{	md->flags = flags;	}void *CONF_module_get_usr_data(CONF_MODULE *pmod)	{	return pmod->usr_data;	}void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)	{	pmod->usr_data = usr_data;	}/* Return default config file name */char *CONF_get1_default_config_file(void)	{	char *file;	int len;	file = getenv("OPENSSL_CONF");	if (file) 		return BUF_strdup(file);	len = strlen(X509_get_default_cert_area());#ifndef OPENSSL_SYS_VMS	len++;#endif	len += strlen(OPENSSL_CONF);	file = OPENSSL_malloc(len + 1);	if (!file)		return NULL;	BUF_strlcpy(file,X509_get_default_cert_area(),len + 1);#ifndef OPENSSL_SYS_VMS	BUF_strlcat(file,"/",len + 1);#endif	BUF_strlcat(file,OPENSSL_CONF,len + 1);	return file;	}/* This function takes a list separated by 'sep' and calls the * callback function giving the start and length of each member * optionally stripping leading and trailing whitespace. This can * be used to parse comma separated lists for example. */int CONF_parse_list(const char *list_, int sep, int nospc,	int (*list_cb)(const char *elem, int len, void *usr), void *arg)	{	int ret;	const char *lstart, *tmpend, *p;	lstart = list_;	for(;;)		{		if (nospc)			{			while(*lstart && isspace((unsigned char)*lstart))				lstart++;			}		p = strchr(lstart, sep);		if (p == lstart || !*lstart)			ret = list_cb(NULL, 0, arg);		else			{			if (p)				tmpend = p - 1;			else 				tmpend = lstart + strlen(lstart) - 1;			if (nospc)				{				while(isspace((unsigned char)*tmpend))					tmpend--;				}			ret = list_cb(lstart, tmpend - lstart + 1, arg);			}		if (ret <= 0)			return ret;		if (p == NULL)			return 1;		lstart = p + 1;		}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -