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

