Commit b9e63915 authored by Geoff Thorpe's avatar Geoff Thorpe
Browse files

This change facilitates name translation for shared libraries. The

technique used is far from perfect and alternatives are welcome.
Basically if the translation flag is set, the string is not too
long, and there appears to be no path information in the string,
then it is converted to whatever the standard should be for the
DSO_METHOD in question, eg;
    blah --> libblah.so   on *nix, and
    blah --> blah.dll     on win32.

This change also introduces the DSO_ctrl() function that is used
by the name translation stuff.
parent 2c8c4ce2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -4,6 +4,13 @@

 Changes between 0.9.5a and 0.9.6  [xx XXX 2000]

  *) Added native name translation to the existing DSO code
     that will convert (if the flag to do so is set) filenames
     that are sufficiently small and have no path information
     into a canonical native form. Eg. "blah" converted to
     "libblah.so" or "blah.dll" etc.
     [Geoff Thorpe]

  *) New function ERR_error_string_n(e, buf, len) which is like
     ERR_error_string(e, buf), but writes at most 'len' bytes
     including the 0 terminator.  For ERR_error_string_n, 'buf'
+41 −13
Original line number Diff line number Diff line
@@ -65,6 +65,20 @@
extern "C" {
#endif

/* These values are used as commands to DSO_ctrl() */
#define DSO_CTRL_GET_FLAGS	1
#define DSO_CTRL_SET_FLAGS	2
#define DSO_CTRL_OR_FLAGS	3

/* These flags control the translation of file-names from canonical to
 * native. Eg. in the CryptoSwift support, the "dl" and "dlfcn"
 * methods will translate "swift" -> "libswift.so" whereas the "win32"
 * method will translate "swift" -> "swift.dll". NB: Until I can figure
 * out how to be more "conventional" with this, the methods will only
 * honour this flag if it looks like it was passed a file without any
 * path and if the filename is small enough.
 */
#define DSO_FLAG_NAME_TRANSLATION 0x01

typedef struct dso_st DSO;

@@ -83,7 +97,11 @@ typedef struct dso_meth_st
	/* Unbinds a symbol */
	int (*dso_unbind)(DSO *dso, char *symname, void *symptr);
#endif
	/* The generic (yuck) "ctrl()" function. NB: Negative return
	 * values (rather than zero) indicate errors. */
	long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg);

	/* [De]Initialisation handlers. */
	int (*init)(DSO *dso);
	int (*finish)(DSO *dso);
	} DSO_METHOD;
@@ -113,6 +131,7 @@ DSO * DSO_new_method(DSO_METHOD *method);
int	DSO_free(DSO *dso);
int	DSO_flags(DSO *dso);
int	DSO_up(DSO *dso);
long	DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);

void DSO_set_default_method(DSO_METHOD *meth);
DSO_METHOD *DSO_get_default_method(void);
@@ -121,8 +140,11 @@ DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);

/* The all-singing all-dancing load function, you normally pass NULL
 * for the first and third parameters. Use DSO_up and DSO_free for
 * reference count handling. */
DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth);
 * subsequent reference count handling. Any flags passed in will be set
 * in the constructed DSO after its init() function but before the
 * load operation. This will be done with;
 *    DSO_ctrl(dso, DSO_CTRL_SET_FLAGS, flags, NULL); */
DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);

/* This function binds to a function, variable, whatever inside a
 * shared library. */
@@ -163,17 +185,21 @@ void ERR_load_DSO_strings(void);
#define DSO_F_DLFCN_BIND				 100
#define DSO_F_DLFCN_LOAD				 101
#define DSO_F_DLFCN_UNLOAD				 102
#define DSO_F_DL_BIND					 103
#define DSO_F_DL_LOAD					 104
#define DSO_F_DL_UNLOAD					 105
#define DSO_F_DSO_BIND					 106
#define DSO_F_DSO_FREE					 107
#define DSO_F_DSO_LOAD					 108
#define DSO_F_DSO_NEW_METHOD				 109
#define DSO_F_DSO_UP					 110
#define DSO_F_WIN32_BIND				 111
#define DSO_F_WIN32_LOAD				 112
#define DSO_F_WIN32_UNLOAD				 113
#define DSO_F_DLFCN_CTRL				 103
#define DSO_F_DL_BIND					 104
#define DSO_F_DL_LOAD					 105
#define DSO_F_DL_UNLOAD					 106
#define DSO_F_DL_CTRL					 107
#define DSO_F_DSO_BIND					 108
#define DSO_F_DSO_FREE					 109
#define DSO_F_DSO_LOAD					 110
#define DSO_F_DSO_NEW_METHOD				 111
#define DSO_F_DSO_UP					 112
#define DSO_F_DSO_CTRL					 113
#define DSO_F_WIN32_BIND				 114
#define DSO_F_WIN32_LOAD				 115
#define DSO_F_WIN32_UNLOAD				 116
#define DSO_F_WIN32_CTRL				 117

/* Reason codes. */
#define DSO_R_FINISH_FAILED				 100
@@ -183,6 +209,8 @@ void ERR_load_DSO_strings(void);
#define DSO_R_SYM_FAILURE				 104
#define DSO_R_UNLOAD_FAILED				 105
#define DSO_R_UNSUPPORTED				 106
#define DSO_R_UNKNOWN_COMMAND				 107
#define DSO_R_CTRL_FAILED				 108

#ifdef  __cplusplus
}
+42 −2
Original line number Diff line number Diff line
@@ -69,6 +69,9 @@ DSO_METHOD *DSO_METHOD_dl(void)

#include <dl.h>

/* Part of the hack in "dl_load" ... */
#define DSO_MAX_TRANSLATED_SIZE 256

static int dl_load(DSO *dso, const char *filename);
static int dl_unload(DSO *dso);
static int dl_bind(DSO *dso, const char *symname, void **symptr);
@@ -77,6 +80,7 @@ static int dl_unbind(DSO *dso, char *symname, void *symptr);
static int dl_init(DSO *dso);
static int dl_finish(DSO *dso);
#endif
static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);

static DSO_METHOD dso_meth_dl = {
	"OpenSSL 'dl' shared library method",
@@ -87,6 +91,7 @@ static DSO_METHOD dso_meth_dl = {
#if 0
	NULL, /* unbind */
#endif
	dl_ctrl,
	NULL, /* init */
	NULL  /* finish */
	};
@@ -105,7 +110,19 @@ DSO_METHOD *DSO_METHOD_dl(void)
static int dl_load(DSO *dso, const char *filename)
	{
	shl_t ptr;
	char translated[DSO_MAX_TRANSLATED_SIZE];
	int len;

	/* The same comment as in dlfcn_load applies here. bleurgh. */
	len = strlen(filename);
	if((dso->flags & DSO_FLAG_NAME_TRANSLATION) &&
			(len + 6 < DSO_MAX_TRANSLATED_SIZE) &&
			(strstr(filename, "/") == NULL))
		{
		sprintf(translated, "lib%s.so", filename);
		ptr = shl_load(translated, BIND_IMMEDIATE, NULL);
		}
	else
		ptr = shl_load(filename, BIND_IMMEDIATE, NULL);
	if(ptr == NULL)
		{
@@ -163,7 +180,6 @@ static int dl_bind(DSO *dso, const char *symname, void **symptr)
		DSOerr(DSO_F_DL_BIND,DSO_R_STACK_ERROR);
		return(0);
		}
	/* Is this actually legal? */
	ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
	if(ptr == NULL)
		{
@@ -179,4 +195,28 @@ static int dl_bind(DSO *dso, const char *symname, void **symptr)
	return(1);
	}

static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg)
	{
	if(dso == NULL)
		{
		DSOerr(DSO_F_DL_CTRL,ERR_R_PASSED_NULL_PARAMETER);
		return(-1);
		}
	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;
		}
	DSOerr(DSO_F_DL_CTRL,DSO_R_UNKNOWN_COMMAND);
	return(-1);
	}

#endif /* DSO_DL */
+47 −1
Original line number Diff line number Diff line
@@ -71,6 +71,9 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
#include <dlfcn.h>
#endif

/* Part of the hack in "dlfcn_load" ... */
#define DSO_MAX_TRANSLATED_SIZE 256

static int dlfcn_load(DSO *dso, const char *filename);
static int dlfcn_unload(DSO *dso);
static int dlfcn_bind(DSO *dso, const char *symname, void **symptr);
@@ -79,6 +82,7 @@ static int dlfcn_unbind(DSO *dso, char *symname, void *symptr);
static int dlfcn_init(DSO *dso);
static int dlfcn_finish(DSO *dso);
#endif
static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);

static DSO_METHOD dso_meth_dlfcn = {
	"OpenSSL 'dlfcn' shared library method",
@@ -89,6 +93,7 @@ static DSO_METHOD dso_meth_dlfcn = {
#if 0
	NULL, /* unbind */
#endif
	dlfcn_ctrl,
	NULL, /* init */
	NULL  /* finish */
	};
@@ -105,8 +110,25 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
static int dlfcn_load(DSO *dso, const char *filename)
	{
	void *ptr;
	char translated[DSO_MAX_TRANSLATED_SIZE];
	int len;

	/* NB: This is a hideous hack, but I'm not yet sure what
	 * to replace it with. This attempts to convert any filename,
	 * that looks like it has no path information, into a
	 * translated form, e. "blah" -> "libblah.so" */
	len = strlen(filename);
	if((dso->flags & DSO_FLAG_NAME_TRANSLATION) &&
			(len + 6 < DSO_MAX_TRANSLATED_SIZE) &&
			(strstr(filename, "/") == NULL))
		{
		sprintf(translated, "lib%s.so", filename);
		ptr = dlopen(translated, RTLD_NOW);
		}
	else
		{
		ptr = dlopen(filename, RTLD_NOW);
		}
	if(ptr == NULL)
		{
		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
@@ -178,4 +200,28 @@ static int dlfcn_bind(DSO *dso, const char *symname, void **symptr)
	return(1);
	}

static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg)
	{
	if(dso == NULL)
		{
		DSOerr(DSO_F_DLFCN_CTRL,ERR_R_PASSED_NULL_PARAMETER);
		return(-1);
		}
	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;
		}
	DSOerr(DSO_F_DLFCN_CTRL,DSO_R_UNKNOWN_COMMAND);
	return(-1);
	}

#endif /* DSO_DLFCN */
+15 −9
Original line number Diff line number Diff line
@@ -66,20 +66,24 @@
#ifndef NO_ERR
static ERR_STRING_DATA DSO_str_functs[]=
	{
{ERR_PACK(0,DSO_F_DLFCN_BIND,0),	"DLFCN_BIND"},
{ERR_PACK(0,DSO_F_DLFCN_LOAD,0),	"DLFCN_LOAD"},
{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0),	"DLFCN_UNLOAD"},
{ERR_PACK(0,DSO_F_DL_BIND,0),	"DL_BIND"},
{ERR_PACK(0,DSO_F_DL_LOAD,0),	"DL_LOAD"},
{ERR_PACK(0,DSO_F_DL_UNLOAD,0),	"DL_UNLOAD"},
{ERR_PACK(0,DSO_F_DLFCN_BIND,0),	"dlfcn_bind"},
{ERR_PACK(0,DSO_F_DLFCN_LOAD,0),	"dlfcn_load"},
{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0),	"dlfcn_unload"},
{ERR_PACK(0,DSO_F_DLFCN_CTRL,0),	"dlfcn_ctrl"},
{ERR_PACK(0,DSO_F_DL_BIND,0),	"dl_bind"},
{ERR_PACK(0,DSO_F_DL_LOAD,0),	"dl_load"},
{ERR_PACK(0,DSO_F_DL_UNLOAD,0),	"dl_unload"},
{ERR_PACK(0,DSO_F_DL_CTRL,0),	"dl_ctrl"},
{ERR_PACK(0,DSO_F_DSO_BIND,0),	"DSO_bind"},
{ERR_PACK(0,DSO_F_DSO_FREE,0),	"DSO_free"},
{ERR_PACK(0,DSO_F_DSO_LOAD,0),	"DSO_load"},
{ERR_PACK(0,DSO_F_DSO_NEW_METHOD,0),	"DSO_new_method"},
{ERR_PACK(0,DSO_F_DSO_UP,0),	"DSO_up"},
{ERR_PACK(0,DSO_F_WIN32_BIND,0),	"WIN32_BIND"},
{ERR_PACK(0,DSO_F_WIN32_LOAD,0),	"WIN32_LOAD"},
{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0),	"WIN32_UNLOAD"},
{ERR_PACK(0,DSO_F_DSO_CTRL,0),	"DSO_ctrl"},
{ERR_PACK(0,DSO_F_WIN32_BIND,0),	"win32_bind"},
{ERR_PACK(0,DSO_F_WIN32_LOAD,0),	"win32_load"},
{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0),	"win32_unload"},
{ERR_PACK(0,DSO_F_WIN32_CTRL,0),	"win32_ctrl"},
{0,NULL}
	};

@@ -92,6 +96,8 @@ static ERR_STRING_DATA DSO_str_reasons[]=
{DSO_R_SYM_FAILURE                       ,"could not bind to the requested symbol name"},
{DSO_R_UNLOAD_FAILED                     ,"could not unload the shared library"},
{DSO_R_UNSUPPORTED                       ,"functionality not supported"},
{DSO_R_UNKNOWN_COMMAND			 ,"unknown control command"},
{DSO_R_CTRL_FAILED			 ,"control command failed"},
{0,NULL}
	};

Loading