/* dso_lib.c -*- mode:C; c-file-style: "eay" -*- */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
 * project 2000.
 */
/* ====================================================================
 * Copyright (c) 2000 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 <openssl/crypto.h>
#include "cryptlib.h"
#include <openssl/dso.h>

static DSO_METHOD *default_DSO_meth = NULL;

DSO *DSO_new(void)
	{
	return(DSO_new_method(NULL));
	}

void DSO_set_default_method(DSO_METHOD *meth)
	{
	default_DSO_meth = meth;
	}

DSO_METHOD *DSO_get_default_method(void)
	{
	return(default_DSO_meth);
	}

DSO_METHOD *DSO_get_method(DSO *dso)
	{
	return(dso->meth);
	}

DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth)
	{
	DSO_METHOD *mtmp;
	mtmp = dso->meth;
	dso->meth = meth;
	return(mtmp);
	}

DSO *DSO_new_method(DSO_METHOD *meth)
	{
	DSO *ret;

	if(default_DSO_meth == NULL)
		/* We default to DSO_METH_openssl() which in turn defaults
		 * to stealing the "best available" method. Will fallback
		 * to DSO_METH_null() in the worst case. */
		default_DSO_meth = DSO_METHOD_openssl();
	ret = (DSO *)OPENSSL_malloc(sizeof(DSO));
	if(ret == NULL)
		{
		DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE);
		return(NULL);
		}
	memset(ret, 0, sizeof(DSO));
	ret->meth_data = sk_void_new_null();
	if(ret->meth_data == NULL)
		{
		/* sk_new doesn't generate any errors so we do */
		DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE);
		OPENSSL_free(ret);
		return(NULL);
		}
	if(meth == NULL)
		ret->meth = default_DSO_meth;
	else
		ret->meth = meth;
	ret->references = 1;
	if((ret->meth->init != NULL) && !ret->meth->init(ret))
		{
		OPENSSL_free(ret);
		ret=NULL;
		}
	return(ret);
	}

int DSO_free(DSO *dso)
	{
        int i;
 
	if(dso == NULL)
		{
		DSOerr(DSO_F_DSO_FREE,ERR_R_PASSED_NULL_PARAMETER);
		return(0);
		}
 
	i=CRYPTO_add(&dso->references,-1,CRYPTO_LOCK_DSO);
#ifdef REF_PRINT
	REF_PRINT("DSO",dso);
#endif
	if(i > 0) return(1);
#ifdef REF_CHECK
	if(i < 0)
		{
		fprintf(stderr,"DSO_free, bad reference count\n");
		abort();
		}
#endif

	if((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso))
		{
		DSOerr(DSO_F_DSO_FREE,DSO_R_UNLOAD_FAILED);
		return(0);
		}
 
	if((dso->meth->finish != NULL) && !dso->meth->finish(dso))
		{
		DSOerr(DSO_F_DSO_FREE,DSO_R_FINISH_FAILED);
		return(0);
		}
	
	sk_void_free(dso->meth_data);
	if(dso->filename != NULL)
		OPENSSL_free(dso->filename);
	if(dso->loaded_filename != NULL)
		OPENSSL_free(dso->loaded_filename);
 
	OPENSSL_free(dso);
	return(1);
	}

int DSO_flags(DSO *dso)
	{
	return((dso == NULL) ? 0 : dso->flags);
	}


int DSO_up_ref(DSO *dso)
	{
	if (dso == NULL)
		{
		DSOerr(DSO_F_DSO_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
		return(0);
		}

	CRYPTO_add(&dso->references,1,CRYPTO_LOCK_DSO);
	return(1);
	}

DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
	{
	DSO *ret;
	int allocated = 0;

	if(dso == NULL)
		{
		ret = DSO_new_method(meth);
		if(ret == NULL)
			{
			DSOerr(DSO_F_DSO_LOAD,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		allocated = 1;
		/* Pass the provided flags to the new DSO object */
		if(DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0)
			{
			DSOerr(DSO_F_DSO_LOAD,DSO_R_CTRL_FAILED);
			goto err;
			}
		}
	else
		ret = dso;
	/* Don't load if we're currently already loaded */
	if(ret->filename != NULL)
		{
		DSOerr(DSO_F_DSO_LOAD,DSO_R_DSO_ALREADY_LOADED);
		goto err;
		}
	/* filename can only be NULL if we were passed a dso that already has
	 * one set. */
	if(filename != NULL)
		if(!DSO_set_filename(ret, filename))
			{
			DSOerr(DSO_F_DSO_LOAD,DSO_R_SET_FILENAME_FAILED);
			goto err;
			}
	filename = ret->filename;
	if(filename == NULL)
		{
		DSOerr(DSO_F_DSO_LOAD,DSO_R_NO_FILENAME);
		goto err;
		}
	if(ret->meth->dso_load == NULL)
		{
		DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED);
		/* Make sure we unset the filename on failure, because we use
		 * this to determine when the DSO has been loaded above. */
		OPENSSL_free(ret->filename);
		ret->filename = NULL;
		goto err;
		}
	if(!ret->meth->dso_load(ret))
		{
		DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED);
		/* Make sure we unset the filename on failure, because we use
		 * this to determine when the DSO has been loaded above. */
		OPENSSL_free(ret->filename);
		ret->filename = NULL;
		goto err;
		}
	/* Load succeeded */
	return(ret);
err:
	if(allocated)
		DSO_free(ret);
	return(NULL);
	}

void *DSO_bind_var(DSO *dso, const char *symname)
	{
	void *ret = NULL;

	if((dso == NULL) || (symname == NULL))
		{
		DSOerr(DSO_F_DSO_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	if(dso->meth->dso_bind_var == NULL)
		{
		DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_UNSUPPORTED);
		return(NULL);
		}
	if((ret = dso->meth->dso_bind_var(dso, symname)) == NULL)
		{
		DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_SYM_FAILURE);
		return(NULL);
		}
	/* Success */
	return(ret);
	}

DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
	{
	DSO_FUNC_TYPE ret = NULL;

	if((dso == NULL) || (symname == NULL))
		{
		DSOerr(DSO_F_DSO_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	if(dso->meth->dso_bind_func == NULL)
		{
		DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_UNSUPPORTED);
		return(NULL);
		}
	if((ret = dso->meth->dso_bind_func(dso, symname)) == NULL)
		{
		DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_SYM_FAILURE);
		return(NULL);
		}
	/* Success */
	return(ret);
	}

/* I don't really like these *_ctrl functions very much to be perfectly
 * honest. For one thing, I think I have to return a negative value for
 * any error because possible DSO_ctrl() commands may return values
 * such as "size"s that can legitimately be zero (making the standard
 * "if(DSO_cmd(...))" form that works almost everywhere else fail at
 * odd times. I'd prefer "output" values to be passed by reference and
 * the return value as success/failure like usual ... but we conform
 * when we must... :-) */
long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
	{
	if(dso == NULL)
		{
		DSOerr(DSO_F_DSO_CTRL,ERR_R_PASSED_NULL_PARAMETER);
		return(-1);
		}
	/* We should intercept certain generic commands and only pass control
	 * to the method-specific ctrl() function if it's something we don't
	 * handle. */
	switch(cmd)
		{
	case DSO_CTRL_GET_FLAGS:
		return dso->flags;
	case DSO_CTRL_SET_FLAGS:
		dso->flags = (int)larg;
		return(0);
	case DSO_CTRL_OR_FLAGS:
		dso->flags |= (int)larg;
		return(0);
	default:
		break;
		}
	if((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL))
		{
		DSOerr(DSO_F_DSO_CTRL,DSO_R_UNSUPPORTED);
		return(-1);
		}
	return(dso->meth->dso_ctrl(dso,cmd,larg,parg));
	}

int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
			DSO_NAME_CONVERTER_FUNC *oldcb)
	{
	if(dso == NULL)
		{
		DSOerr(DSO_F_DSO_SET_NAME_CONVERTER,
				ERR_R_PASSED_NULL_PARAMETER);
		return(0);
		}
	if(oldcb)
		*oldcb = dso->name_converter;
	dso->name_converter = cb;
	return(1);
	}

const char *DSO_get_filename(DSO *dso)
	{
	if(dso == NULL)
		{
		DSOerr(DSO_F_DSO_GET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	return(dso->filename);
	}

int DSO_set_filename(DSO *dso, const char *filename)
	{
	char *copied;

	if((dso == NULL) || (filename == NULL))
		{
		DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
		return(0);
		}
	if(dso->loaded_filename)
		{
		DSOerr(DSO_F_DSO_SET_FILENAME,DSO_R_DSO_ALREADY_LOADED);
		return(0);
		}
	/* We'll duplicate filename */
	copied = OPENSSL_malloc(strlen(filename) + 1);
	if(copied == NULL)
		{
		DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_MALLOC_FAILURE);
		return(0);
		}
	BUF_strlcpy(copied, filename, strlen(filename) + 1);
	if(dso->filename)
		OPENSSL_free(dso->filename);
	dso->filename = copied;
	return(1);
	}

char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
	{
	char *result = NULL;

	if(dso == NULL || filespec1 == NULL)
		{
		DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
		{
		if(dso->merger != NULL)
			result = dso->merger(dso, filespec1, filespec2);
		else if(dso->meth->dso_merger != NULL)
			result = dso->meth->dso_merger(dso,
				filespec1, filespec2);
		}
	return(result);
	}

char *DSO_convert_filename(DSO *dso, const char *filename)
	{
	char *result = NULL;

	if(dso == NULL)
		{
		DSOerr(DSO_F_DSO_CONVERT_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	if(filename == NULL)
		filename = dso->filename;
	if(filename == NULL)
		{
		DSOerr(DSO_F_DSO_CONVERT_FILENAME,DSO_R_NO_FILENAME);
		return(NULL);
		}
	if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
		{
		if(dso->name_converter != NULL)
			result = dso->name_converter(dso, filename);
		else if(dso->meth->dso_name_converter != NULL)
			result = dso->meth->dso_name_converter(dso, filename);
		}
	if(result == NULL)
		{
		result = OPENSSL_malloc(strlen(filename) + 1);
		if(result == NULL)
			{
			DSOerr(DSO_F_DSO_CONVERT_FILENAME,
					ERR_R_MALLOC_FAILURE);
			return(NULL);
			}
		BUF_strlcpy(result, filename, strlen(filename) + 1);
		}
	return(result);
	}

const char *DSO_get_loaded_filename(DSO *dso)
	{
	if(dso == NULL)
		{
		DSOerr(DSO_F_DSO_GET_LOADED_FILENAME,
				ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	return(dso->loaded_filename);
	}

int DSO_pathbyaddr(void *addr,char *path,int sz)
	{
	DSO_METHOD *meth = default_DSO_meth;
	if (meth == NULL) meth = DSO_METHOD_openssl();
	if (meth->pathbyaddr == NULL)
		{
		DSOerr(DSO_F_DSO_PATHBYADDR,DSO_R_UNSUPPORTED);
		return -1;
		}
	return (*meth->pathbyaddr)(addr,path,sz);
	}

void *DSO_global_lookup(const char *name)
	{
	DSO_METHOD *meth = default_DSO_meth;
	if (meth == NULL) meth = DSO_METHOD_openssl();
	if (meth->globallookup == NULL)
		{
		DSOerr(DSO_F_DSO_GLOBAL_LOOKUP,DSO_R_UNSUPPORTED);
		return NULL;
		}
	return (*meth->globallookup)(name);
	}
