/* conf_mod.c */
/* Written by Stephen Henson (shenson@bigfoot.com) 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;

	int ret, i;

	if (!cnf)
		return 1;

	if (appname == NULL)
		appname = "openssl_conf";

	vsection = NCONF_get_string(cnf, NULL, appname); 

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

