summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/dso
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/dso')
-rw-r--r--src/lib/libcrypto/dso/dso.h168
-rw-r--r--src/lib/libcrypto/dso/dso_dlfcn.c99
-rw-r--r--src/lib/libcrypto/dso/dso_err.c23
-rw-r--r--src/lib/libcrypto/dso/dso_lib.c179
4 files changed, 347 insertions, 122 deletions
diff --git a/src/lib/libcrypto/dso/dso.h b/src/lib/libcrypto/dso/dso.h
index bed7c464a6..aa721f7feb 100644
--- a/src/lib/libcrypto/dso/dso.h
+++ b/src/lib/libcrypto/dso/dso.h
@@ -70,31 +70,51 @@ extern "C" {
70#define DSO_CTRL_SET_FLAGS 2 70#define DSO_CTRL_SET_FLAGS 2
71#define DSO_CTRL_OR_FLAGS 3 71#define DSO_CTRL_OR_FLAGS 3
72 72
73/* These flags control the translation of file-names from canonical to 73/* By default, DSO_load() will translate the provided filename into a form
74 * native. Eg. in the CryptoSwift support, the "dl" and "dlfcn" 74 * typical for the platform (more specifically the DSO_METHOD) using the
75 * methods will translate "swift" -> "libswift.so" whereas the "win32" 75 * dso_name_converter function of the method. Eg. win32 will transform "blah"
76 * method will translate "swift" -> "swift.dll". NB: Until I can figure 76 * into "blah.dll", and dlfcn will transform it into "libblah.so". The
77 * out how to be more "conventional" with this, the methods will only 77 * behaviour can be overriden by setting the name_converter callback in the DSO
78 * honour this flag if it looks like it was passed a file without any 78 * object (using DSO_set_name_converter()). This callback could even utilise
79 * path and if the filename is small enough. 79 * the DSO_METHOD's converter too if it only wants to override behaviour for
80 */ 80 * one or two possible DSO methods. However, the following flag can be set in a
81#define DSO_FLAG_NAME_TRANSLATION 0x01 81 * DSO to prevent *any* native name-translation at all - eg. if the caller has
82 * prompted the user for a path to a driver library so the filename should be
83 * interpreted as-is. */
84#define DSO_FLAG_NO_NAME_TRANSLATION 0x01
85/* An extra flag to give if only the extension should be added as
86 * translation. This is obviously only of importance on Unix and
87 * other operating systems where the translation also may prefix
88 * the name with something, like 'lib', and ignored everywhere else.
89 * This flag is also ignored if DSO_FLAG_NO_NAME_TRANSLATION is used
90 * at the same time. */
91#define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY 0x02
82 92
83/* The following flag controls the translation of symbol names to upper 93/* The following flag controls the translation of symbol names to upper
84 * case. This is currently only being implemented for OpenVMS. 94 * case. This is currently only being implemented for OpenVMS.
85 */ 95 */
86#define DSO_FLAG_UPCASE_SYMBOL 0x02 96#define DSO_FLAG_UPCASE_SYMBOL 0x10
87 97
88 98
89typedef void (*DSO_FUNC_TYPE)(void); 99typedef void (*DSO_FUNC_TYPE)(void);
90 100
91typedef struct dso_st DSO; 101typedef struct dso_st DSO;
92 102
103/* The function prototype used for method functions (or caller-provided
104 * callbacks) that transform filenames. They are passed a DSO structure pointer
105 * (or NULL if they are to be used independantly of a DSO object) and a
106 * filename to transform. They should either return NULL (if there is an error
107 * condition) or a newly allocated string containing the transformed form that
108 * the caller will need to free with OPENSSL_free() when done. */
109typedef char* (*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
110
93typedef struct dso_meth_st 111typedef struct dso_meth_st
94 { 112 {
95 const char *name; 113 const char *name;
96 /* Loads a shared library */ 114 /* Loads a shared library, NB: new DSO_METHODs must ensure that a
97 int (*dso_load)(DSO *dso, const char *filename); 115 * successful load populates the loaded_filename field, and likewise a
116 * successful unload OPENSSL_frees and NULLs it out. */
117 int (*dso_load)(DSO *dso);
98 /* Unloads a shared library */ 118 /* Unloads a shared library */
99 int (*dso_unload)(DSO *dso); 119 int (*dso_unload)(DSO *dso);
100 /* Binds a variable */ 120 /* Binds a variable */
@@ -117,6 +137,9 @@ typedef struct dso_meth_st
117 /* The generic (yuck) "ctrl()" function. NB: Negative return 137 /* The generic (yuck) "ctrl()" function. NB: Negative return
118 * values (rather than zero) indicate errors. */ 138 * values (rather than zero) indicate errors. */
119 long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg); 139 long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg);
140 /* The default DSO_METHOD-specific function for converting filenames to
141 * a canonical native form. */
142 DSO_NAME_CONVERTER_FUNC dso_name_converter;
120 143
121 /* [De]Initialisation handlers. */ 144 /* [De]Initialisation handlers. */
122 int (*init)(DSO *dso); 145 int (*init)(DSO *dso);
@@ -140,6 +163,23 @@ struct dso_st
140 /* For use by applications etc ... use this for your bits'n'pieces, 163 /* For use by applications etc ... use this for your bits'n'pieces,
141 * don't touch meth_data! */ 164 * don't touch meth_data! */
142 CRYPTO_EX_DATA ex_data; 165 CRYPTO_EX_DATA ex_data;
166 /* If this callback function pointer is set to non-NULL, then it will
167 * be used on DSO_load() in place of meth->dso_name_converter. NB: This
168 * should normally set using DSO_set_name_converter(). */
169 DSO_NAME_CONVERTER_FUNC name_converter;
170 /* This is populated with (a copy of) the platform-independant
171 * filename used for this DSO. */
172 char *filename;
173 /* This is populated with (a copy of) the translated filename by which
174 * the DSO was actually loaded. It is NULL iff the DSO is not currently
175 * loaded. NB: This is here because the filename translation process
176 * may involve a callback being invoked more than once not only to
177 * convert to a platform-specific form, but also to try different
178 * filenames in the process of trying to perform a load. As such, this
179 * variable can be used to indicate (a) whether this DSO structure
180 * corresponds to a loaded library or not, and (b) the filename with
181 * which it was actually loaded. */
182 char *loaded_filename;
143 }; 183 };
144 184
145 185
@@ -147,10 +187,38 @@ DSO * DSO_new(void);
147DSO * DSO_new_method(DSO_METHOD *method); 187DSO * DSO_new_method(DSO_METHOD *method);
148int DSO_free(DSO *dso); 188int DSO_free(DSO *dso);
149int DSO_flags(DSO *dso); 189int DSO_flags(DSO *dso);
150int DSO_up(DSO *dso); 190int DSO_up_ref(DSO *dso);
151long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg); 191long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);
152 192
153void DSO_set_default_method(DSO_METHOD *meth); 193/* This function sets the DSO's name_converter callback. If it is non-NULL,
194 * then it will be used instead of the associated DSO_METHOD's function. If
195 * oldcb is non-NULL then it is set to the function pointer value being
196 * replaced. Return value is non-zero for success. */
197int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
198 DSO_NAME_CONVERTER_FUNC *oldcb);
199/* These functions can be used to get/set the platform-independant filename
200 * used for a DSO. NB: set will fail if the DSO is already loaded. */
201const char *DSO_get_filename(DSO *dso);
202int DSO_set_filename(DSO *dso, const char *filename);
203/* This function will invoke the DSO's name_converter callback to translate a
204 * filename, or if the callback isn't set it will instead use the DSO_METHOD's
205 * converter. If "filename" is NULL, the "filename" in the DSO itself will be
206 * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is
207 * simply duplicated. NB: This function is usually called from within a
208 * DSO_METHOD during the processing of a DSO_load() call, and is exposed so that
209 * caller-created DSO_METHODs can do the same thing. A non-NULL return value
210 * will need to be OPENSSL_free()'d. */
211char *DSO_convert_filename(DSO *dso, const char *filename);
212/* If the DSO is currently loaded, this returns the filename that it was loaded
213 * under, otherwise it returns NULL. So it is also useful as a test as to
214 * whether the DSO is currently loaded. NB: This will not necessarily return
215 * the same value as DSO_convert_filename(dso, dso->filename), because the
216 * DSO_METHOD's load function may have tried a variety of filenames (with
217 * and/or without the aid of the converters) before settling on the one it
218 * actually loaded. */
219const char *DSO_get_loaded_filename(DSO *dso);
220
221void DSO_set_default_method(DSO_METHOD *meth);
154DSO_METHOD *DSO_get_default_method(void); 222DSO_METHOD *DSO_get_default_method(void);
155DSO_METHOD *DSO_get_method(DSO *dso); 223DSO_METHOD *DSO_get_method(DSO *dso);
156DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth); 224DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);
@@ -159,8 +227,7 @@ DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);
159 * for the first and third parameters. Use DSO_up and DSO_free for 227 * for the first and third parameters. Use DSO_up and DSO_free for
160 * subsequent reference count handling. Any flags passed in will be set 228 * subsequent reference count handling. Any flags passed in will be set
161 * in the constructed DSO after its init() function but before the 229 * in the constructed DSO after its init() function but before the
162 * load operation. This will be done with; 230 * load operation. If 'dso' is non-NULL, 'flags' is ignored. */
163 * DSO_ctrl(dso, DSO_CTRL_SET_FLAGS, flags, NULL); */
164DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags); 231DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);
165 232
166/* This function binds to a variable inside a shared library. */ 233/* This function binds to a variable inside a shared library. */
@@ -194,52 +261,58 @@ DSO_METHOD *DSO_METHOD_win32(void);
194/* If VMS is defined, use shared images. If not, return NULL. */ 261/* If VMS is defined, use shared images. If not, return NULL. */
195DSO_METHOD *DSO_METHOD_vms(void); 262DSO_METHOD *DSO_METHOD_vms(void);
196 263
197void ERR_load_DSO_strings(void);
198
199/* BEGIN ERROR CODES */ 264/* BEGIN ERROR CODES */
200/* The following lines are auto generated by the script mkerr.pl. Any changes 265/* The following lines are auto generated by the script mkerr.pl. Any changes
201 * made after this point may be overwritten when the script is next run. 266 * made after this point may be overwritten when the script is next run.
202 */ 267 */
268void ERR_load_DSO_strings(void);
203 269
204/* Error codes for the DSO functions. */ 270/* Error codes for the DSO functions. */
205 271
206/* Function codes. */ 272/* Function codes. */
207#define DSO_F_DLFCN_BIND_FUNC 100 273#define DSO_F_DLFCN_BIND_FUNC 100
208#define DSO_F_DLFCN_BIND_VAR 101 274#define DSO_F_DLFCN_BIND_VAR 101
209#define DSO_F_DLFCN_CTRL 102 275#define DSO_F_DLFCN_LOAD 102
210#define DSO_F_DLFCN_LOAD 103 276#define DSO_F_DLFCN_NAME_CONVERTER 123
211#define DSO_F_DLFCN_UNLOAD 104 277#define DSO_F_DLFCN_UNLOAD 103
212#define DSO_F_DL_BIND_FUNC 105 278#define DSO_F_DL_BIND_FUNC 104
213#define DSO_F_DL_BIND_VAR 106 279#define DSO_F_DL_BIND_VAR 105
214#define DSO_F_DL_CTRL 107 280#define DSO_F_DL_LOAD 106
215#define DSO_F_DL_LOAD 108 281#define DSO_F_DL_NAME_CONVERTER 124
216#define DSO_F_DL_UNLOAD 109 282#define DSO_F_DL_UNLOAD 107
217#define DSO_F_DSO_BIND_FUNC 110 283#define DSO_F_DSO_BIND_FUNC 108
218#define DSO_F_DSO_BIND_VAR 111 284#define DSO_F_DSO_BIND_VAR 109
219#define DSO_F_DSO_CTRL 112 285#define DSO_F_DSO_CONVERT_FILENAME 126
220#define DSO_F_DSO_FREE 113 286#define DSO_F_DSO_CTRL 110
221#define DSO_F_DSO_LOAD 114 287#define DSO_F_DSO_FREE 111
222#define DSO_F_DSO_NEW_METHOD 115 288#define DSO_F_DSO_GET_FILENAME 127
223#define DSO_F_DSO_UP 116 289#define DSO_F_DSO_GET_LOADED_FILENAME 128
224#define DSO_F_VMS_BIND_VAR 122 290#define DSO_F_DSO_LOAD 112
225#define DSO_F_VMS_CTRL 123 291#define DSO_F_DSO_NEW_METHOD 113
226#define DSO_F_VMS_LOAD 124 292#define DSO_F_DSO_SET_FILENAME 129
227#define DSO_F_VMS_UNLOAD 125 293#define DSO_F_DSO_SET_NAME_CONVERTER 122
228#define DSO_F_WIN32_BIND_FUNC 117 294#define DSO_F_DSO_UP_REF 114
229#define DSO_F_WIN32_BIND_VAR 118 295#define DSO_F_VMS_BIND_VAR 115
230#define DSO_F_WIN32_CTRL 119 296#define DSO_F_VMS_LOAD 116
297#define DSO_F_VMS_UNLOAD 117
298#define DSO_F_WIN32_BIND_FUNC 118
299#define DSO_F_WIN32_BIND_VAR 119
231#define DSO_F_WIN32_LOAD 120 300#define DSO_F_WIN32_LOAD 120
301#define DSO_F_WIN32_NAME_CONVERTER 125
232#define DSO_F_WIN32_UNLOAD 121 302#define DSO_F_WIN32_UNLOAD 121
233 303
234/* Reason codes. */ 304/* Reason codes. */
235#define DSO_R_CTRL_FAILED 100 305#define DSO_R_CTRL_FAILED 100
236#define DSO_R_FILENAME_TOO_BIG 109 306#define DSO_R_DSO_ALREADY_LOADED 110
237#define DSO_R_FINISH_FAILED 101 307#define DSO_R_FILENAME_TOO_BIG 101
238#define DSO_R_LOAD_FAILED 102 308#define DSO_R_FINISH_FAILED 102
239#define DSO_R_NULL_HANDLE 103 309#define DSO_R_LOAD_FAILED 103
240#define DSO_R_STACK_ERROR 104 310#define DSO_R_NAME_TRANSLATION_FAILED 109
241#define DSO_R_SYM_FAILURE 105 311#define DSO_R_NO_FILENAME 111
242#define DSO_R_UNKNOWN_COMMAND 106 312#define DSO_R_NULL_HANDLE 104
313#define DSO_R_SET_FILENAME_FAILED 112
314#define DSO_R_STACK_ERROR 105
315#define DSO_R_SYM_FAILURE 106
243#define DSO_R_UNLOAD_FAILED 107 316#define DSO_R_UNLOAD_FAILED 107
244#define DSO_R_UNSUPPORTED 108 317#define DSO_R_UNSUPPORTED 108
245 318
@@ -247,4 +320,3 @@ void ERR_load_DSO_strings(void);
247} 320}
248#endif 321#endif
249#endif 322#endif
250
diff --git a/src/lib/libcrypto/dso/dso_dlfcn.c b/src/lib/libcrypto/dso/dso_dlfcn.c
index e709c721cc..906b4703de 100644
--- a/src/lib/libcrypto/dso/dso_dlfcn.c
+++ b/src/lib/libcrypto/dso/dso_dlfcn.c
@@ -74,7 +74,7 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
74/* Part of the hack in "dlfcn_load" ... */ 74/* Part of the hack in "dlfcn_load" ... */
75#define DSO_MAX_TRANSLATED_SIZE 256 75#define DSO_MAX_TRANSLATED_SIZE 256
76 76
77static int dlfcn_load(DSO *dso, const char *filename); 77static int dlfcn_load(DSO *dso);
78static int dlfcn_unload(DSO *dso); 78static int dlfcn_unload(DSO *dso);
79static void *dlfcn_bind_var(DSO *dso, const char *symname); 79static void *dlfcn_bind_var(DSO *dso, const char *symname);
80static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname); 80static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
@@ -82,8 +82,9 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
82static int dlfcn_unbind(DSO *dso, char *symname, void *symptr); 82static int dlfcn_unbind(DSO *dso, char *symname, void *symptr);
83static int dlfcn_init(DSO *dso); 83static int dlfcn_init(DSO *dso);
84static int dlfcn_finish(DSO *dso); 84static int dlfcn_finish(DSO *dso);
85#endif
86static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); 85static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
86#endif
87static char *dlfcn_name_converter(DSO *dso, const char *filename);
87 88
88static DSO_METHOD dso_meth_dlfcn = { 89static DSO_METHOD dso_meth_dlfcn = {
89 "OpenSSL 'dlfcn' shared library method", 90 "OpenSSL 'dlfcn' shared library method",
@@ -96,7 +97,8 @@ static DSO_METHOD dso_meth_dlfcn = {
96 NULL, /* unbind_var */ 97 NULL, /* unbind_var */
97 NULL, /* unbind_func */ 98 NULL, /* unbind_func */
98#endif 99#endif
99 dlfcn_ctrl, 100 NULL, /* ctrl */
101 dlfcn_name_converter,
100 NULL, /* init */ 102 NULL, /* init */
101 NULL /* finish */ 103 NULL /* finish */
102 }; 104 };
@@ -112,7 +114,7 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
112 * as we don't have autoconf yet, I'm implementing a hack that could 114 * as we don't have autoconf yet, I'm implementing a hack that could
113 * be hacked further relatively easily to deal with cases as we find 115 * be hacked further relatively easily to deal with cases as we find
114 * them. Initially this is to cope with OpenBSD. */ 116 * them. Initially this is to cope with OpenBSD. */
115#ifdef __OpenBSD__ 117#if defined(__OpenBSD__) || defined(__NetBSD__)
116# ifdef DL_LAZY 118# ifdef DL_LAZY
117# define DLOPEN_FLAG DL_LAZY 119# define DLOPEN_FLAG DL_LAZY
118# else 120# else
@@ -130,41 +132,40 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
130 * (i) the handle (void*) returned from dlopen(). 132 * (i) the handle (void*) returned from dlopen().
131 */ 133 */
132 134
133static int dlfcn_load(DSO *dso, const char *filename) 135static int dlfcn_load(DSO *dso)
134 { 136 {
135 void *ptr; 137 void *ptr = NULL;
136 char translated[DSO_MAX_TRANSLATED_SIZE]; 138 /* See applicable comments in dso_dl.c */
137 int len; 139 char *filename = DSO_convert_filename(dso, NULL);
138 140
139 /* NB: This is a hideous hack, but I'm not yet sure what 141 if(filename == NULL)
140 * to replace it with. This attempts to convert any filename,
141 * that looks like it has no path information, into a
142 * translated form, e. "blah" -> "libblah.so" */
143 len = strlen(filename);
144 if((dso->flags & DSO_FLAG_NAME_TRANSLATION) &&
145 (len + 6 < DSO_MAX_TRANSLATED_SIZE) &&
146 (strstr(filename, "/") == NULL))
147 { 142 {
148 sprintf(translated, "lib%s.so", filename); 143 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME);
149 ptr = dlopen(translated, DLOPEN_FLAG); 144 goto err;
150 }
151 else
152 {
153 ptr = dlopen(filename, DLOPEN_FLAG);
154 } 145 }
146 ptr = dlopen(filename, DLOPEN_FLAG);
155 if(ptr == NULL) 147 if(ptr == NULL)
156 { 148 {
157 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED); 149 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
158 return(0); 150 ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
151 goto err;
159 } 152 }
160 if(!sk_push(dso->meth_data, (char *)ptr)) 153 if(!sk_push(dso->meth_data, (char *)ptr))
161 { 154 {
162 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR); 155 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR);
163 dlclose(ptr); 156 goto err;
164 return(0);
165 } 157 }
158 /* Success */
159 dso->loaded_filename = filename;
166 return(1); 160 return(1);
167 } 161err:
162 /* Cleanup! */
163 if(filename != NULL)
164 OPENSSL_free(filename);
165 if(ptr != NULL)
166 dlclose(ptr);
167 return(0);
168}
168 169
169static int dlfcn_unload(DSO *dso) 170static int dlfcn_unload(DSO *dso)
170 { 171 {
@@ -214,6 +215,7 @@ static void *dlfcn_bind_var(DSO *dso, const char *symname)
214 if(sym == NULL) 215 if(sym == NULL)
215 { 216 {
216 DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_SYM_FAILURE); 217 DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_SYM_FAILURE);
218 ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
217 return(NULL); 219 return(NULL);
218 } 220 }
219 return(sym); 221 return(sym);
@@ -244,33 +246,44 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
244 if(sym == NULL) 246 if(sym == NULL)
245 { 247 {
246 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE); 248 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
249 ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
247 return(NULL); 250 return(NULL);
248 } 251 }
249 return(sym); 252 return(sym);
250 } 253 }
251 254
252static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg) 255static char *dlfcn_name_converter(DSO *dso, const char *filename)
253 { 256 {
254 if(dso == NULL) 257 char *translated;
258 int len, rsize, transform;
259
260 len = strlen(filename);
261 rsize = len + 1;
262 transform = (strstr(filename, "/") == NULL);
263 if(transform)
255 { 264 {
256 DSOerr(DSO_F_DLFCN_CTRL,ERR_R_PASSED_NULL_PARAMETER); 265 /* We will convert this to "%s.so" or "lib%s.so" */
257 return(-1); 266 rsize += 3; /* The length of ".so" */
267 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
268 rsize += 3; /* The length of "lib" */
258 } 269 }
259 switch(cmd) 270 translated = OPENSSL_malloc(rsize);
271 if(translated == NULL)
260 { 272 {
261 case DSO_CTRL_GET_FLAGS: 273 DSOerr(DSO_F_DLFCN_NAME_CONVERTER,
262 return dso->flags; 274 DSO_R_NAME_TRANSLATION_FAILED);
263 case DSO_CTRL_SET_FLAGS: 275 return(NULL);
264 dso->flags = (int)larg;
265 return(0);
266 case DSO_CTRL_OR_FLAGS:
267 dso->flags |= (int)larg;
268 return(0);
269 default:
270 break;
271 } 276 }
272 DSOerr(DSO_F_DLFCN_CTRL,DSO_R_UNKNOWN_COMMAND); 277 if(transform)
273 return(-1); 278 {
279 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
280 sprintf(translated, "lib%s.so", filename);
281 else
282 sprintf(translated, "%s.so", filename);
283 }
284 else
285 sprintf(translated, "%s", filename);
286 return(translated);
274 } 287 }
275 288
276#endif /* DSO_DLFCN */ 289#endif /* DSO_DLFCN */
diff --git a/src/lib/libcrypto/dso/dso_err.c b/src/lib/libcrypto/dso/dso_err.c
index a3d7321c9b..cf452de1aa 100644
--- a/src/lib/libcrypto/dso/dso_err.c
+++ b/src/lib/libcrypto/dso/dso_err.c
@@ -63,34 +63,38 @@
63#include <openssl/dso.h> 63#include <openssl/dso.h>
64 64
65/* BEGIN ERROR CODES */ 65/* BEGIN ERROR CODES */
66#ifndef NO_ERR 66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA DSO_str_functs[]= 67static ERR_STRING_DATA DSO_str_functs[]=
68 { 68 {
69{ERR_PACK(0,DSO_F_DLFCN_BIND_FUNC,0), "DLFCN_BIND_FUNC"}, 69{ERR_PACK(0,DSO_F_DLFCN_BIND_FUNC,0), "DLFCN_BIND_FUNC"},
70{ERR_PACK(0,DSO_F_DLFCN_BIND_VAR,0), "DLFCN_BIND_VAR"}, 70{ERR_PACK(0,DSO_F_DLFCN_BIND_VAR,0), "DLFCN_BIND_VAR"},
71{ERR_PACK(0,DSO_F_DLFCN_CTRL,0), "DLFCN_CTRL"},
72{ERR_PACK(0,DSO_F_DLFCN_LOAD,0), "DLFCN_LOAD"}, 71{ERR_PACK(0,DSO_F_DLFCN_LOAD,0), "DLFCN_LOAD"},
72{ERR_PACK(0,DSO_F_DLFCN_NAME_CONVERTER,0), "DLFCN_NAME_CONVERTER"},
73{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0), "DLFCN_UNLOAD"}, 73{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0), "DLFCN_UNLOAD"},
74{ERR_PACK(0,DSO_F_DL_BIND_FUNC,0), "DL_BIND_FUNC"}, 74{ERR_PACK(0,DSO_F_DL_BIND_FUNC,0), "DL_BIND_FUNC"},
75{ERR_PACK(0,DSO_F_DL_BIND_VAR,0), "DL_BIND_VAR"}, 75{ERR_PACK(0,DSO_F_DL_BIND_VAR,0), "DL_BIND_VAR"},
76{ERR_PACK(0,DSO_F_DL_CTRL,0), "DL_CTRL"},
77{ERR_PACK(0,DSO_F_DL_LOAD,0), "DL_LOAD"}, 76{ERR_PACK(0,DSO_F_DL_LOAD,0), "DL_LOAD"},
77{ERR_PACK(0,DSO_F_DL_NAME_CONVERTER,0), "DL_NAME_CONVERTER"},
78{ERR_PACK(0,DSO_F_DL_UNLOAD,0), "DL_UNLOAD"}, 78{ERR_PACK(0,DSO_F_DL_UNLOAD,0), "DL_UNLOAD"},
79{ERR_PACK(0,DSO_F_DSO_BIND_FUNC,0), "DSO_bind_func"}, 79{ERR_PACK(0,DSO_F_DSO_BIND_FUNC,0), "DSO_bind_func"},
80{ERR_PACK(0,DSO_F_DSO_BIND_VAR,0), "DSO_bind_var"}, 80{ERR_PACK(0,DSO_F_DSO_BIND_VAR,0), "DSO_bind_var"},
81{ERR_PACK(0,DSO_F_DSO_CONVERT_FILENAME,0), "DSO_convert_filename"},
81{ERR_PACK(0,DSO_F_DSO_CTRL,0), "DSO_ctrl"}, 82{ERR_PACK(0,DSO_F_DSO_CTRL,0), "DSO_ctrl"},
82{ERR_PACK(0,DSO_F_DSO_FREE,0), "DSO_free"}, 83{ERR_PACK(0,DSO_F_DSO_FREE,0), "DSO_free"},
84{ERR_PACK(0,DSO_F_DSO_GET_FILENAME,0), "DSO_get_filename"},
85{ERR_PACK(0,DSO_F_DSO_GET_LOADED_FILENAME,0), "DSO_get_loaded_filename"},
83{ERR_PACK(0,DSO_F_DSO_LOAD,0), "DSO_load"}, 86{ERR_PACK(0,DSO_F_DSO_LOAD,0), "DSO_load"},
84{ERR_PACK(0,DSO_F_DSO_NEW_METHOD,0), "DSO_new_method"}, 87{ERR_PACK(0,DSO_F_DSO_NEW_METHOD,0), "DSO_new_method"},
85{ERR_PACK(0,DSO_F_DSO_UP,0), "DSO_up"}, 88{ERR_PACK(0,DSO_F_DSO_SET_FILENAME,0), "DSO_set_filename"},
89{ERR_PACK(0,DSO_F_DSO_SET_NAME_CONVERTER,0), "DSO_set_name_converter"},
90{ERR_PACK(0,DSO_F_DSO_UP_REF,0), "DSO_up_ref"},
86{ERR_PACK(0,DSO_F_VMS_BIND_VAR,0), "VMS_BIND_VAR"}, 91{ERR_PACK(0,DSO_F_VMS_BIND_VAR,0), "VMS_BIND_VAR"},
87{ERR_PACK(0,DSO_F_VMS_CTRL,0), "VMS_CTRL"},
88{ERR_PACK(0,DSO_F_VMS_LOAD,0), "VMS_LOAD"}, 92{ERR_PACK(0,DSO_F_VMS_LOAD,0), "VMS_LOAD"},
89{ERR_PACK(0,DSO_F_VMS_UNLOAD,0), "VMS_UNLOAD"}, 93{ERR_PACK(0,DSO_F_VMS_UNLOAD,0), "VMS_UNLOAD"},
90{ERR_PACK(0,DSO_F_WIN32_BIND_FUNC,0), "WIN32_BIND_FUNC"}, 94{ERR_PACK(0,DSO_F_WIN32_BIND_FUNC,0), "WIN32_BIND_FUNC"},
91{ERR_PACK(0,DSO_F_WIN32_BIND_VAR,0), "WIN32_BIND_VAR"}, 95{ERR_PACK(0,DSO_F_WIN32_BIND_VAR,0), "WIN32_BIND_VAR"},
92{ERR_PACK(0,DSO_F_WIN32_CTRL,0), "WIN32_CTRL"},
93{ERR_PACK(0,DSO_F_WIN32_LOAD,0), "WIN32_LOAD"}, 96{ERR_PACK(0,DSO_F_WIN32_LOAD,0), "WIN32_LOAD"},
97{ERR_PACK(0,DSO_F_WIN32_NAME_CONVERTER,0), "WIN32_NAME_CONVERTER"},
94{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0), "WIN32_UNLOAD"}, 98{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0), "WIN32_UNLOAD"},
95{0,NULL} 99{0,NULL}
96 }; 100 };
@@ -98,13 +102,16 @@ static ERR_STRING_DATA DSO_str_functs[]=
98static ERR_STRING_DATA DSO_str_reasons[]= 102static ERR_STRING_DATA DSO_str_reasons[]=
99 { 103 {
100{DSO_R_CTRL_FAILED ,"control command failed"}, 104{DSO_R_CTRL_FAILED ,"control command failed"},
105{DSO_R_DSO_ALREADY_LOADED ,"dso already loaded"},
101{DSO_R_FILENAME_TOO_BIG ,"filename too big"}, 106{DSO_R_FILENAME_TOO_BIG ,"filename too big"},
102{DSO_R_FINISH_FAILED ,"cleanup method function failed"}, 107{DSO_R_FINISH_FAILED ,"cleanup method function failed"},
103{DSO_R_LOAD_FAILED ,"could not load the shared library"}, 108{DSO_R_LOAD_FAILED ,"could not load the shared library"},
109{DSO_R_NAME_TRANSLATION_FAILED ,"name translation failed"},
110{DSO_R_NO_FILENAME ,"no filename"},
104{DSO_R_NULL_HANDLE ,"a null shared library handle was used"}, 111{DSO_R_NULL_HANDLE ,"a null shared library handle was used"},
112{DSO_R_SET_FILENAME_FAILED ,"set filename failed"},
105{DSO_R_STACK_ERROR ,"the meth_data stack is corrupt"}, 113{DSO_R_STACK_ERROR ,"the meth_data stack is corrupt"},
106{DSO_R_SYM_FAILURE ,"could not bind to the requested symbol name"}, 114{DSO_R_SYM_FAILURE ,"could not bind to the requested symbol name"},
107{DSO_R_UNKNOWN_COMMAND ,"unknown control command"},
108{DSO_R_UNLOAD_FAILED ,"could not unload the shared library"}, 115{DSO_R_UNLOAD_FAILED ,"could not unload the shared library"},
109{DSO_R_UNSUPPORTED ,"functionality not supported"}, 116{DSO_R_UNSUPPORTED ,"functionality not supported"},
110{0,NULL} 117{0,NULL}
@@ -119,7 +126,7 @@ void ERR_load_DSO_strings(void)
119 if (init) 126 if (init)
120 { 127 {
121 init=0; 128 init=0;
122#ifndef NO_ERR 129#ifndef OPENSSL_NO_ERR
123 ERR_load_strings(ERR_LIB_DSO,DSO_str_functs); 130 ERR_load_strings(ERR_LIB_DSO,DSO_str_functs);
124 ERR_load_strings(ERR_LIB_DSO,DSO_str_reasons); 131 ERR_load_strings(ERR_LIB_DSO,DSO_str_reasons);
125#endif 132#endif
diff --git a/src/lib/libcrypto/dso/dso_lib.c b/src/lib/libcrypto/dso/dso_lib.c
index acd166697e..556069b9b8 100644
--- a/src/lib/libcrypto/dso/dso_lib.c
+++ b/src/lib/libcrypto/dso/dso_lib.c
@@ -108,7 +108,7 @@ DSO *DSO_new_method(DSO_METHOD *meth)
108 } 108 }
109 memset(ret, 0, sizeof(DSO)); 109 memset(ret, 0, sizeof(DSO));
110 ret->meth_data = sk_new_null(); 110 ret->meth_data = sk_new_null();
111 if((ret->meth_data = sk_new_null()) == NULL) 111 if(ret->meth_data == NULL)
112 { 112 {
113 /* sk_new doesn't generate any errors so we do */ 113 /* sk_new doesn't generate any errors so we do */
114 DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE); 114 DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE);
@@ -164,6 +164,10 @@ int DSO_free(DSO *dso)
164 } 164 }
165 165
166 sk_free(dso->meth_data); 166 sk_free(dso->meth_data);
167 if(dso->filename != NULL)
168 OPENSSL_free(dso->filename);
169 if(dso->loaded_filename != NULL)
170 OPENSSL_free(dso->loaded_filename);
167 171
168 OPENSSL_free(dso); 172 OPENSSL_free(dso);
169 return(1); 173 return(1);
@@ -175,11 +179,11 @@ int DSO_flags(DSO *dso)
175 } 179 }
176 180
177 181
178int DSO_up(DSO *dso) 182int DSO_up_ref(DSO *dso)
179 { 183 {
180 if (dso == NULL) 184 if (dso == NULL)
181 { 185 {
182 DSOerr(DSO_F_DSO_UP,ERR_R_PASSED_NULL_PARAMETER); 186 DSOerr(DSO_F_DSO_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
183 return(0); 187 return(0);
184 } 188 }
185 189
@@ -192,48 +196,60 @@ DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
192 DSO *ret; 196 DSO *ret;
193 int allocated = 0; 197 int allocated = 0;
194 198
195 if(filename == NULL)
196 {
197 DSOerr(DSO_F_DSO_LOAD,ERR_R_PASSED_NULL_PARAMETER);
198 return(NULL);
199 }
200 if(dso == NULL) 199 if(dso == NULL)
201 { 200 {
202 ret = DSO_new_method(meth); 201 ret = DSO_new_method(meth);
203 if(ret == NULL) 202 if(ret == NULL)
204 { 203 {
205 DSOerr(DSO_F_DSO_LOAD,ERR_R_MALLOC_FAILURE); 204 DSOerr(DSO_F_DSO_LOAD,ERR_R_MALLOC_FAILURE);
206 return(NULL); 205 goto err;
207 } 206 }
208 allocated = 1; 207 allocated = 1;
208 /* Pass the provided flags to the new DSO object */
209 if(DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0)
210 {
211 DSOerr(DSO_F_DSO_LOAD,DSO_R_CTRL_FAILED);
212 goto err;
213 }
209 } 214 }
210 else 215 else
211 ret = dso; 216 ret = dso;
212 /* Bleurgh ... have to check for negative return values for 217 /* Don't load if we're currently already loaded */
213 * errors. <grimace> */ 218 if(ret->filename != NULL)
214 if(DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0)
215 { 219 {
216 DSOerr(DSO_F_DSO_LOAD,DSO_R_CTRL_FAILED); 220 DSOerr(DSO_F_DSO_LOAD,DSO_R_DSO_ALREADY_LOADED);
217 if(allocated) 221 goto err;
218 DSO_free(ret); 222 }
219 return(NULL); 223 /* filename can only be NULL if we were passed a dso that already has
224 * one set. */
225 if(filename != NULL)
226 if(!DSO_set_filename(ret, filename))
227 {
228 DSOerr(DSO_F_DSO_LOAD,DSO_R_SET_FILENAME_FAILED);
229 goto err;
230 }
231 filename = ret->filename;
232 if(filename == NULL)
233 {
234 DSOerr(DSO_F_DSO_LOAD,DSO_R_NO_FILENAME);
235 goto err;
220 } 236 }
221 if(ret->meth->dso_load == NULL) 237 if(ret->meth->dso_load == NULL)
222 { 238 {
223 DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED); 239 DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED);
224 if(allocated) 240 goto err;
225 DSO_free(ret);
226 return(NULL);
227 } 241 }
228 if(!ret->meth->dso_load(ret, filename)) 242 if(!ret->meth->dso_load(ret))
229 { 243 {
230 DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED); 244 DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED);
231 if(allocated) 245 goto err;
232 DSO_free(ret);
233 return(NULL);
234 } 246 }
235 /* Load succeeded */ 247 /* Load succeeded */
236 return(ret); 248 return(ret);
249err:
250 if(allocated)
251 DSO_free(ret);
252 return(NULL);
237 } 253 }
238 254
239void *DSO_bind_var(DSO *dso, const char *symname) 255void *DSO_bind_var(DSO *dso, const char *symname)
@@ -297,6 +313,22 @@ long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
297 DSOerr(DSO_F_DSO_CTRL,ERR_R_PASSED_NULL_PARAMETER); 313 DSOerr(DSO_F_DSO_CTRL,ERR_R_PASSED_NULL_PARAMETER);
298 return(-1); 314 return(-1);
299 } 315 }
316 /* We should intercept certain generic commands and only pass control
317 * to the method-specific ctrl() function if it's something we don't
318 * handle. */
319 switch(cmd)
320 {
321 case DSO_CTRL_GET_FLAGS:
322 return dso->flags;
323 case DSO_CTRL_SET_FLAGS:
324 dso->flags = (int)larg;
325 return(0);
326 case DSO_CTRL_OR_FLAGS:
327 dso->flags |= (int)larg;
328 return(0);
329 default:
330 break;
331 }
300 if((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) 332 if((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL))
301 { 333 {
302 DSOerr(DSO_F_DSO_CTRL,DSO_R_UNSUPPORTED); 334 DSOerr(DSO_F_DSO_CTRL,DSO_R_UNSUPPORTED);
@@ -304,3 +336,104 @@ long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
304 } 336 }
305 return(dso->meth->dso_ctrl(dso,cmd,larg,parg)); 337 return(dso->meth->dso_ctrl(dso,cmd,larg,parg));
306 } 338 }
339
340int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
341 DSO_NAME_CONVERTER_FUNC *oldcb)
342 {
343 if(dso == NULL)
344 {
345 DSOerr(DSO_F_DSO_SET_NAME_CONVERTER,
346 ERR_R_PASSED_NULL_PARAMETER);
347 return(0);
348 }
349 if(oldcb)
350 *oldcb = dso->name_converter;
351 dso->name_converter = cb;
352 return(1);
353 }
354
355const char *DSO_get_filename(DSO *dso)
356 {
357 if(dso == NULL)
358 {
359 DSOerr(DSO_F_DSO_GET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
360 return(NULL);
361 }
362 return(dso->filename);
363 }
364
365int DSO_set_filename(DSO *dso, const char *filename)
366 {
367 char *copied;
368
369 if((dso == NULL) || (filename == NULL))
370 {
371 DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
372 return(0);
373 }
374 if(dso->loaded_filename)
375 {
376 DSOerr(DSO_F_DSO_SET_FILENAME,DSO_R_DSO_ALREADY_LOADED);
377 return(0);
378 }
379 /* We'll duplicate filename */
380 copied = OPENSSL_malloc(strlen(filename) + 1);
381 if(copied == NULL)
382 {
383 DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_MALLOC_FAILURE);
384 return(0);
385 }
386 strcpy(copied, filename);
387 if(dso->filename)
388 OPENSSL_free(dso->filename);
389 dso->filename = copied;
390 return(1);
391 }
392
393char *DSO_convert_filename(DSO *dso, const char *filename)
394 {
395 char *result = NULL;
396
397 if(dso == NULL)
398 {
399 DSOerr(DSO_F_DSO_CONVERT_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
400 return(NULL);
401 }
402 if(filename == NULL)
403 filename = dso->filename;
404 if(filename == NULL)
405 {
406 DSOerr(DSO_F_DSO_CONVERT_FILENAME,DSO_R_NO_FILENAME);
407 return(NULL);
408 }
409 if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
410 {
411 if(dso->name_converter != NULL)
412 result = dso->name_converter(dso, filename);
413 else if(dso->meth->dso_name_converter != NULL)
414 result = dso->meth->dso_name_converter(dso, filename);
415 }
416 if(result == NULL)
417 {
418 result = OPENSSL_malloc(strlen(filename) + 1);
419 if(result == NULL)
420 {
421 DSOerr(DSO_F_DSO_CONVERT_FILENAME,
422 ERR_R_MALLOC_FAILURE);
423 return(NULL);
424 }
425 strcpy(result, filename);
426 }
427 return(result);
428 }
429
430const char *DSO_get_loaded_filename(DSO *dso)
431 {
432 if(dso == NULL)
433 {
434 DSOerr(DSO_F_DSO_GET_LOADED_FILENAME,
435 ERR_R_PASSED_NULL_PARAMETER);
436 return(NULL);
437 }
438 return(dso->loaded_filename);
439 }