/* 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;
		}
	}

