Commit cbecb3ac authored by Richard Levitte's avatar Richard Levitte
Browse files

There's an ongoing project to bring some kind of path selection

mechanism to the ENGINE framework.  This means there there are going
to be new functionality for the DSO part, and ultimately some way of
merging two file specifications together.

This commit places the merging code into the repository.  It's
currently not used anywhere, and hasn't been tested at all.  It may be
full of errors, including syntactical ones.  Those will be fixed as
promptly as possible.
parent 5dbd3efc
Loading
Loading
Loading
Loading
+38 −2
Original line number Diff line number Diff line
/* dso.h */
/* dso.h -*- mode:C; c-file-style: "eay" -*- */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
 * project 2000.
 */
@@ -107,6 +107,22 @@ typedef struct dso_st DSO;
 * condition) or a newly allocated string containing the transformed form that
 * the caller will need to free with OPENSSL_free() when done. */
typedef char* (*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
/* The function prototype used for method functions (or caller-provided
 * callbacks) that merge two file specifications. They are passed a
 * DSO structure pointer (or NULL if they are to be used independantly of
 * a DSO object) and two file specifications to merge. They should
 * either return NULL (if there is an error condition) or a newly allocated
 * string containing the result of merging that the caller will need
 * to free with OPENSSL_free() when done.
 * Here, merging means that bits and pieces are taken from each of the
 * file specifications and added together in whatever fashion that is
 * sensible for the DSO method in question.  The only rule that really
 * applies is that if the two specification contain pieces of the same
 * type, the copy from the string string takes priority.  One could see
 * it as the first specification is the one given by the user and the
 * second being a bunch of defaults to add on if they're missing in the
 * first. */
typedef char* (*DSO_MERGER_FUNC)(DSO *, const char *, const char *);

typedef struct dso_meth_st
	{
@@ -140,6 +156,9 @@ typedef struct dso_meth_st
	/* The default DSO_METHOD-specific function for converting filenames to
	 * a canonical native form. */
	DSO_NAME_CONVERTER_FUNC dso_name_converter;
	/* The default DSO_METHOD-specific function for converting filenames to
	 * a canonical native form. */
	DSO_MERGER_FUNC dso_merger;

	/* [De]Initialisation handlers. */
	int (*init)(DSO *dso);
@@ -164,9 +183,13 @@ struct dso_st
	 * don't touch meth_data! */
	CRYPTO_EX_DATA ex_data;
	/* If this callback function pointer is set to non-NULL, then it will
	 * be used on DSO_load() in place of meth->dso_name_converter. NB: This
	 * be used in DSO_load() in place of meth->dso_name_converter. NB: This
	 * should normally set using DSO_set_name_converter(). */
	DSO_NAME_CONVERTER_FUNC name_converter;
	/* If this callback function pointer is set to non-NULL, then it will
	 * be used in DSO_load() in place of meth->dso_merger. NB: This
	 * should normally set using DSO_set_merger(). */
	DSO_MERGER_FUNC merger;
	/* This is populated with (a copy of) the platform-independant
	 * filename used for this DSO. */
	char *filename;
@@ -209,6 +232,11 @@ int DSO_set_filename(DSO *dso, const char *filename);
 * caller-created DSO_METHODs can do the same thing. A non-NULL return value
 * will need to be OPENSSL_free()'d. */
char	*DSO_convert_filename(DSO *dso, const char *filename);
/* This function will invoke the DSO's merger callback to merge two file
 * specifications, or if the callback isn't set it will instead use the
 * DSO_METHOD's merger.  A non-NULL return value will need to be
 * OPENSSL_free()'d. */
char	*DSO_merge(DSO *dso, const char *filespec1, const char *filespec2);
/* If the DSO is currently loaded, this returns the filename that it was loaded
 * under, otherwise it returns NULL. So it is also useful as a test as to
 * whether the DSO is currently loaded. NB: This will not necessarily return
@@ -273,11 +301,13 @@ void ERR_load_DSO_strings(void);
#define DSO_F_DLFCN_BIND_FUNC				 100
#define DSO_F_DLFCN_BIND_VAR				 101
#define DSO_F_DLFCN_LOAD				 102
#define DSO_F_DLFCN_MERGER				 130
#define DSO_F_DLFCN_NAME_CONVERTER			 123
#define DSO_F_DLFCN_UNLOAD				 103
#define DSO_F_DL_BIND_FUNC				 104
#define DSO_F_DL_BIND_VAR				 105
#define DSO_F_DL_LOAD					 106
#define DSO_F_DL_MERGER					 131
#define DSO_F_DL_NAME_CONVERTER				 124
#define DSO_F_DL_UNLOAD					 107
#define DSO_F_DSO_BIND_FUNC				 108
@@ -288,24 +318,30 @@ void ERR_load_DSO_strings(void);
#define DSO_F_DSO_GET_FILENAME				 127
#define DSO_F_DSO_GET_LOADED_FILENAME			 128
#define DSO_F_DSO_LOAD					 112
#define DSO_F_DSO_MERGE					 132
#define DSO_F_DSO_NEW_METHOD				 113
#define DSO_F_DSO_SET_FILENAME				 129
#define DSO_F_DSO_SET_NAME_CONVERTER			 122
#define DSO_F_DSO_UP_REF				 114
#define DSO_F_VMS_BIND_VAR				 115
#define DSO_F_VMS_LOAD					 116
#define DSO_F_VMS_MERGER				 133
#define DSO_F_VMS_UNLOAD				 117
#define DSO_F_WIN32_BIND_FUNC				 118
#define DSO_F_WIN32_BIND_VAR				 119
#define DSO_F_WIN32_LOAD				 120
#define DSO_F_WIN32_MERGER				 134
#define DSO_F_WIN32_NAME_CONVERTER			 125
#define DSO_F_WIN32_UNLOAD				 121

/* Reason codes. */
#define DSO_R_CTRL_FAILED				 100
#define DSO_R_DSO_ALREADY_LOADED			 110
#define DSO_R_EMPTY_FILE_STRUCTURE			 113
#define DSO_R_FAILURE					 114
#define DSO_R_FILENAME_TOO_BIG				 101
#define DSO_R_FINISH_FAILED				 102
#define DSO_R_INCORRECT_FILE_SYNTAX			 115
#define DSO_R_LOAD_FAILED				 103
#define DSO_R_NAME_TRANSLATION_FAILED			 109
#define DSO_R_NO_FILENAME				 111
+69 −1
Original line number Diff line number Diff line
/* dso_dl.c */
/* dso_dl.c -*- mode:C; c-file-style: "eay" -*- */
/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
 * project 2000.
 */
@@ -84,6 +84,7 @@ static int dl_finish(DSO *dso);
static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
#endif
static char *dl_name_converter(DSO *dso, const char *filename);
static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);

static DSO_METHOD dso_meth_dl = {
	"OpenSSL 'dl' shared library method",
@@ -98,6 +99,7 @@ static DSO_METHOD dso_meth_dl = {
#endif
	NULL, /* ctrl */
	dl_name_converter,
	dl_merger,
	NULL, /* init */
	NULL  /* finish */
	};
@@ -238,6 +240,72 @@ static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
	return((DSO_FUNC_TYPE)sym);
	}

static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
	{
	char *merged;

	if(!filespec1 && !filespec2)
		{
		DSOerr(DSO_F_DL_MERGER,
				ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	/* If the first file specification is a rooted path, it rules.
	   same goes if the second file specification is missing. */
	if (!filespec2 || filespec1[0] == '/')
		{
		merged = OPENSSL_malloc(strlen(filespec1) + 1);
		if(!merged)
			{
			DSOerr(DSO_F_DL_MERGER,
				ERR_R_MALLOC_FAILURE);
			return(NULL);
			}
		strcpy(merged, filespec1);
		}
	/* If the first file specification is missing, the second one rules. */
	else if (!filespec1)
		{
		merged = OPENSSL_malloc(strlen(filespec2) + 1);
		if(!merged)
			{
			DSOerr(DSO_F_DL_MERGER,
				ERR_R_MALLOC_FAILURE);
			return(NULL);
			}
		strcpy(merged, filespec2);
		}
	else
		/* This part isn't as trivial as it looks.  It assumes that
		   the second file specification really is a directory, and
		   makes no checks whatsoever.  Therefore, the result becomes
		   the concatenation of filespec2 followed by a slash followed
		   by filespec1. */
		{
		int spec2len, len;

		spec2len = (filespec2 ? strlen(filespec2) : 0);
		len = spec2len + (filespec1 ? strlen(filespec1) : 0);

		if(filespec2 && filespec2[spec2len - 1] == '/')
			{
			spec2len--;
			len--;
			}
		merged = OPENSSL_malloc(len + 2);
		if(!merged)
			{
			DSOerr(DSO_F_DL_MERGER,
				ERR_R_MALLOC_FAILURE);
			return(NULL);
			}
		strcpy(merged, filespec2);
		merged[spec2len] = '/';
		strcpy(&merged[spec2len + 1], filespec1);
		}
	return(merged);
	}

/* This function is identical to the one in dso_dlfcn.c, but as it is highly
 * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at the
 * same time, there's no great duplicating the code. Figuring out an elegant 
+71 −1
Original line number Diff line number Diff line
/* dso_dlfcn.c */
/* dso_dlfcn.c -*- mode:C; c-file-style: "eay" -*- */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
 * project 2000.
 */
@@ -85,6 +85,8 @@ static int dlfcn_finish(DSO *dso);
static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
#endif
static char *dlfcn_name_converter(DSO *dso, const char *filename);
static char *dlfcn_merger(DSO *dso, const char *filespec1,
	const char *filespec2);

static DSO_METHOD dso_meth_dlfcn = {
	"OpenSSL 'dlfcn' shared library method",
@@ -99,6 +101,7 @@ static DSO_METHOD dso_meth_dlfcn = {
#endif
	NULL, /* ctrl */
	dlfcn_name_converter,
	dlfcn_merger,
	NULL, /* init */
	NULL  /* finish */
	};
@@ -252,6 +255,73 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
	return(sym);
	}

static char *dlfcn_merger(DSO *dso, const char *filespec1,
	const char *filespec2)
	{
	char *merged;

	if(!filespec1 && !filespec2)
		{
		DSOerr(DSO_F_DLFCN_MERGER,
				ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	/* If the first file specification is a rooted path, it rules.
	   same goes if the second file specification is missing. */
	if (!filespec2 || filespec1[0] == '/')
		{
		merged = OPENSSL_malloc(strlen(filespec1) + 1);
		if(!merged)
			{
			DSOerr(DSO_F_DLFCN_MERGER,
				ERR_R_MALLOC_FAILURE);
			return(NULL);
			}
		strcpy(merged, filespec1);
		}
	/* If the first file specification is missing, the second one rules. */
	else if (!filespec1)
		{
		merged = OPENSSL_malloc(strlen(filespec2) + 1);
		if(!merged)
			{
			DSOerr(DSO_F_DLFCN_MERGER,
				ERR_R_MALLOC_FAILURE);
			return(NULL);
			}
		strcpy(merged, filespec2);
		}
	else
		/* This part isn't as trivial as it looks.  It assumes that
		   the second file specification really is a directory, and
		   makes no checks whatsoever.  Therefore, the result becomes
		   the concatenation of filespec2 followed by a slash followed
		   by filespec1. */
		{
		int spec2len, len;

		spec2len = (filespec2 ? strlen(filespec2) : 0);
		len = spec2len + (filespec1 ? strlen(filespec1) : 0);

		if(filespec2 && filespec2[spec2len - 1] == '/')
			{
			spec2len--;
			len--;
			}
		merged = OPENSSL_malloc(len + 2);
		if(!merged)
			{
			DSOerr(DSO_F_DLFCN_MERGER,
				ERR_R_MALLOC_FAILURE);
			return(NULL);
			}
		strcpy(merged, filespec2);
		merged[spec2len] = '/';
		strcpy(&merged[spec2len + 1], filespec1);
		}
	return(merged);
	}

static char *dlfcn_name_converter(DSO *dso, const char *filename)
	{
	char *translated;
+9 −1
Original line number Diff line number Diff line
/* crypto/dso/dso_err.c */
/* ====================================================================
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
 * Copyright (c) 1999-2002 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
@@ -69,11 +69,13 @@ static ERR_STRING_DATA DSO_str_functs[]=
{ERR_PACK(0,DSO_F_DLFCN_BIND_FUNC,0),	"DLFCN_BIND_FUNC"},
{ERR_PACK(0,DSO_F_DLFCN_BIND_VAR,0),	"DLFCN_BIND_VAR"},
{ERR_PACK(0,DSO_F_DLFCN_LOAD,0),	"DLFCN_LOAD"},
{ERR_PACK(0,DSO_F_DLFCN_MERGER,0),	"DLFCN_MERGER"},
{ERR_PACK(0,DSO_F_DLFCN_NAME_CONVERTER,0),	"DLFCN_NAME_CONVERTER"},
{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0),	"DLFCN_UNLOAD"},
{ERR_PACK(0,DSO_F_DL_BIND_FUNC,0),	"DL_BIND_FUNC"},
{ERR_PACK(0,DSO_F_DL_BIND_VAR,0),	"DL_BIND_VAR"},
{ERR_PACK(0,DSO_F_DL_LOAD,0),	"DL_LOAD"},
{ERR_PACK(0,DSO_F_DL_MERGER,0),	"DL_MERGER"},
{ERR_PACK(0,DSO_F_DL_NAME_CONVERTER,0),	"DL_NAME_CONVERTER"},
{ERR_PACK(0,DSO_F_DL_UNLOAD,0),	"DL_UNLOAD"},
{ERR_PACK(0,DSO_F_DSO_BIND_FUNC,0),	"DSO_bind_func"},
@@ -84,16 +86,19 @@ static ERR_STRING_DATA DSO_str_functs[]=
{ERR_PACK(0,DSO_F_DSO_GET_FILENAME,0),	"DSO_get_filename"},
{ERR_PACK(0,DSO_F_DSO_GET_LOADED_FILENAME,0),	"DSO_get_loaded_filename"},
{ERR_PACK(0,DSO_F_DSO_LOAD,0),	"DSO_load"},
{ERR_PACK(0,DSO_F_DSO_MERGE,0),	"DSO_merge"},
{ERR_PACK(0,DSO_F_DSO_NEW_METHOD,0),	"DSO_new_method"},
{ERR_PACK(0,DSO_F_DSO_SET_FILENAME,0),	"DSO_set_filename"},
{ERR_PACK(0,DSO_F_DSO_SET_NAME_CONVERTER,0),	"DSO_set_name_converter"},
{ERR_PACK(0,DSO_F_DSO_UP_REF,0),	"DSO_up_ref"},
{ERR_PACK(0,DSO_F_VMS_BIND_VAR,0),	"VMS_BIND_VAR"},
{ERR_PACK(0,DSO_F_VMS_LOAD,0),	"VMS_LOAD"},
{ERR_PACK(0,DSO_F_VMS_MERGER,0),	"VMS_MERGER"},
{ERR_PACK(0,DSO_F_VMS_UNLOAD,0),	"VMS_UNLOAD"},
{ERR_PACK(0,DSO_F_WIN32_BIND_FUNC,0),	"WIN32_BIND_FUNC"},
{ERR_PACK(0,DSO_F_WIN32_BIND_VAR,0),	"WIN32_BIND_VAR"},
{ERR_PACK(0,DSO_F_WIN32_LOAD,0),	"WIN32_LOAD"},
{ERR_PACK(0,DSO_F_WIN32_MERGER,0),	"WIN32_MERGER"},
{ERR_PACK(0,DSO_F_WIN32_NAME_CONVERTER,0),	"WIN32_NAME_CONVERTER"},
{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0),	"WIN32_UNLOAD"},
{0,NULL}
@@ -103,8 +108,11 @@ static ERR_STRING_DATA DSO_str_reasons[]=
	{
{DSO_R_CTRL_FAILED                       ,"control command failed"},
{DSO_R_DSO_ALREADY_LOADED                ,"dso already loaded"},
{DSO_R_EMPTY_FILE_STRUCTURE              ,"empty file structure"},
{DSO_R_FAILURE                           ,"failure"},
{DSO_R_FILENAME_TOO_BIG                  ,"filename too big"},
{DSO_R_FINISH_FAILED                     ,"cleanup method function failed"},
{DSO_R_INCORRECT_FILE_SYNTAX             ,"incorrect file syntax"},
{DSO_R_LOAD_FAILED                       ,"could not load the shared library"},
{DSO_R_NAME_TRANSLATION_FAILED           ,"name translation failed"},
{DSO_R_NO_FILENAME                       ,"no filename"},
+28 −1
Original line number Diff line number Diff line
/* dso_lib.c */
/* dso_lib.c -*- mode:C; c-file-style: "eay" -*- */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
 * project 2000.
 */
@@ -390,6 +390,33 @@ int DSO_set_filename(DSO *dso, const char *filename)
	return(1);
	}

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

	if(dso == NULL || dir == NULL)
		{
		DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER);
		return(NULL);
		}
	if(filespec1 == NULL)
		filespec1 = dso->filename;
	if(filespec1 == NULL)
		{
		DSOerr(DSO_F_DSO_MERGE,DSO_R_NO_FILENAME);
		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;
Loading