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.h52
-rw-r--r--src/lib/libcrypto/dso/dso_dl.c102
-rw-r--r--src/lib/libcrypto/dso/dso_dlfcn.c114
-rw-r--r--src/lib/libcrypto/dso/dso_err.c22
-rw-r--r--src/lib/libcrypto/dso/dso_lib.c29
-rw-r--r--src/lib/libcrypto/dso/dso_null.c2
-rw-r--r--src/lib/libcrypto/dso/dso_vms.c137
-rw-r--r--src/lib/libcrypto/dso/dso_win32.c364
8 files changed, 736 insertions, 86 deletions
diff --git a/src/lib/libcrypto/dso/dso.h b/src/lib/libcrypto/dso/dso.h
index aa721f7feb..3e51913a72 100644
--- a/src/lib/libcrypto/dso/dso.h
+++ b/src/lib/libcrypto/dso/dso.h
@@ -1,4 +1,4 @@
1/* dso.h */ 1/* dso.h -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL 2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -95,6 +95,13 @@ extern "C" {
95 */ 95 */
96#define DSO_FLAG_UPCASE_SYMBOL 0x10 96#define DSO_FLAG_UPCASE_SYMBOL 0x10
97 97
98/* This flag loads the library with public symbols.
99 * Meaning: The exported symbols of this library are public
100 * to all libraries loaded after this library.
101 * At the moment only implemented in unix.
102 */
103#define DSO_FLAG_GLOBAL_SYMBOLS 0x20
104
98 105
99typedef void (*DSO_FUNC_TYPE)(void); 106typedef void (*DSO_FUNC_TYPE)(void);
100 107
@@ -107,6 +114,22 @@ typedef struct dso_st DSO;
107 * condition) or a newly allocated string containing the transformed form that 114 * condition) or a newly allocated string containing the transformed form that
108 * the caller will need to free with OPENSSL_free() when done. */ 115 * the caller will need to free with OPENSSL_free() when done. */
109typedef char* (*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *); 116typedef char* (*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
117/* The function prototype used for method functions (or caller-provided
118 * callbacks) that merge two file specifications. They are passed a
119 * DSO structure pointer (or NULL if they are to be used independantly of
120 * a DSO object) and two file specifications to merge. They should
121 * either return NULL (if there is an error condition) or a newly allocated
122 * string containing the result of merging that the caller will need
123 * to free with OPENSSL_free() when done.
124 * Here, merging means that bits and pieces are taken from each of the
125 * file specifications and added together in whatever fashion that is
126 * sensible for the DSO method in question. The only rule that really
127 * applies is that if the two specification contain pieces of the same
128 * type, the copy from the first string takes priority. One could see
129 * it as the first specification is the one given by the user and the
130 * second being a bunch of defaults to add on if they're missing in the
131 * first. */
132typedef char* (*DSO_MERGER_FUNC)(DSO *, const char *, const char *);
110 133
111typedef struct dso_meth_st 134typedef struct dso_meth_st
112 { 135 {
@@ -140,6 +163,9 @@ typedef struct dso_meth_st
140 /* The default DSO_METHOD-specific function for converting filenames to 163 /* The default DSO_METHOD-specific function for converting filenames to
141 * a canonical native form. */ 164 * a canonical native form. */
142 DSO_NAME_CONVERTER_FUNC dso_name_converter; 165 DSO_NAME_CONVERTER_FUNC dso_name_converter;
166 /* The default DSO_METHOD-specific function for converting filenames to
167 * a canonical native form. */
168 DSO_MERGER_FUNC dso_merger;
143 169
144 /* [De]Initialisation handlers. */ 170 /* [De]Initialisation handlers. */
145 int (*init)(DSO *dso); 171 int (*init)(DSO *dso);
@@ -164,9 +190,13 @@ struct dso_st
164 * don't touch meth_data! */ 190 * don't touch meth_data! */
165 CRYPTO_EX_DATA ex_data; 191 CRYPTO_EX_DATA ex_data;
166 /* If this callback function pointer is set to non-NULL, then it will 192 /* 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 193 * be used in DSO_load() in place of meth->dso_name_converter. NB: This
168 * should normally set using DSO_set_name_converter(). */ 194 * should normally set using DSO_set_name_converter(). */
169 DSO_NAME_CONVERTER_FUNC name_converter; 195 DSO_NAME_CONVERTER_FUNC name_converter;
196 /* If this callback function pointer is set to non-NULL, then it will
197 * be used in DSO_load() in place of meth->dso_merger. NB: This
198 * should normally set using DSO_set_merger(). */
199 DSO_MERGER_FUNC merger;
170 /* This is populated with (a copy of) the platform-independant 200 /* This is populated with (a copy of) the platform-independant
171 * filename used for this DSO. */ 201 * filename used for this DSO. */
172 char *filename; 202 char *filename;
@@ -209,6 +239,11 @@ int DSO_set_filename(DSO *dso, const char *filename);
209 * caller-created DSO_METHODs can do the same thing. A non-NULL return value 239 * caller-created DSO_METHODs can do the same thing. A non-NULL return value
210 * will need to be OPENSSL_free()'d. */ 240 * will need to be OPENSSL_free()'d. */
211char *DSO_convert_filename(DSO *dso, const char *filename); 241char *DSO_convert_filename(DSO *dso, const char *filename);
242/* This function will invoke the DSO's merger callback to merge two file
243 * specifications, or if the callback isn't set it will instead use the
244 * DSO_METHOD's merger. A non-NULL return value will need to be
245 * OPENSSL_free()'d. */
246char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2);
212/* If the DSO is currently loaded, this returns the filename that it was loaded 247/* 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 248 * 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 249 * whether the DSO is currently loaded. NB: This will not necessarily return
@@ -273,11 +308,13 @@ void ERR_load_DSO_strings(void);
273#define DSO_F_DLFCN_BIND_FUNC 100 308#define DSO_F_DLFCN_BIND_FUNC 100
274#define DSO_F_DLFCN_BIND_VAR 101 309#define DSO_F_DLFCN_BIND_VAR 101
275#define DSO_F_DLFCN_LOAD 102 310#define DSO_F_DLFCN_LOAD 102
311#define DSO_F_DLFCN_MERGER 130
276#define DSO_F_DLFCN_NAME_CONVERTER 123 312#define DSO_F_DLFCN_NAME_CONVERTER 123
277#define DSO_F_DLFCN_UNLOAD 103 313#define DSO_F_DLFCN_UNLOAD 103
278#define DSO_F_DL_BIND_FUNC 104 314#define DSO_F_DL_BIND_FUNC 104
279#define DSO_F_DL_BIND_VAR 105 315#define DSO_F_DL_BIND_VAR 105
280#define DSO_F_DL_LOAD 106 316#define DSO_F_DL_LOAD 106
317#define DSO_F_DL_MERGER 131
281#define DSO_F_DL_NAME_CONVERTER 124 318#define DSO_F_DL_NAME_CONVERTER 124
282#define DSO_F_DL_UNLOAD 107 319#define DSO_F_DL_UNLOAD 107
283#define DSO_F_DSO_BIND_FUNC 108 320#define DSO_F_DSO_BIND_FUNC 108
@@ -288,27 +325,36 @@ void ERR_load_DSO_strings(void);
288#define DSO_F_DSO_GET_FILENAME 127 325#define DSO_F_DSO_GET_FILENAME 127
289#define DSO_F_DSO_GET_LOADED_FILENAME 128 326#define DSO_F_DSO_GET_LOADED_FILENAME 128
290#define DSO_F_DSO_LOAD 112 327#define DSO_F_DSO_LOAD 112
328#define DSO_F_DSO_MERGE 132
291#define DSO_F_DSO_NEW_METHOD 113 329#define DSO_F_DSO_NEW_METHOD 113
292#define DSO_F_DSO_SET_FILENAME 129 330#define DSO_F_DSO_SET_FILENAME 129
293#define DSO_F_DSO_SET_NAME_CONVERTER 122 331#define DSO_F_DSO_SET_NAME_CONVERTER 122
294#define DSO_F_DSO_UP_REF 114 332#define DSO_F_DSO_UP_REF 114
295#define DSO_F_VMS_BIND_VAR 115 333#define DSO_F_VMS_BIND_SYM 115
296#define DSO_F_VMS_LOAD 116 334#define DSO_F_VMS_LOAD 116
335#define DSO_F_VMS_MERGER 133
297#define DSO_F_VMS_UNLOAD 117 336#define DSO_F_VMS_UNLOAD 117
298#define DSO_F_WIN32_BIND_FUNC 118 337#define DSO_F_WIN32_BIND_FUNC 118
299#define DSO_F_WIN32_BIND_VAR 119 338#define DSO_F_WIN32_BIND_VAR 119
339#define DSO_F_WIN32_JOINER 135
300#define DSO_F_WIN32_LOAD 120 340#define DSO_F_WIN32_LOAD 120
341#define DSO_F_WIN32_MERGER 134
301#define DSO_F_WIN32_NAME_CONVERTER 125 342#define DSO_F_WIN32_NAME_CONVERTER 125
343#define DSO_F_WIN32_SPLITTER 136
302#define DSO_F_WIN32_UNLOAD 121 344#define DSO_F_WIN32_UNLOAD 121
303 345
304/* Reason codes. */ 346/* Reason codes. */
305#define DSO_R_CTRL_FAILED 100 347#define DSO_R_CTRL_FAILED 100
306#define DSO_R_DSO_ALREADY_LOADED 110 348#define DSO_R_DSO_ALREADY_LOADED 110
349#define DSO_R_EMPTY_FILE_STRUCTURE 113
350#define DSO_R_FAILURE 114
307#define DSO_R_FILENAME_TOO_BIG 101 351#define DSO_R_FILENAME_TOO_BIG 101
308#define DSO_R_FINISH_FAILED 102 352#define DSO_R_FINISH_FAILED 102
353#define DSO_R_INCORRECT_FILE_SYNTAX 115
309#define DSO_R_LOAD_FAILED 103 354#define DSO_R_LOAD_FAILED 103
310#define DSO_R_NAME_TRANSLATION_FAILED 109 355#define DSO_R_NAME_TRANSLATION_FAILED 109
311#define DSO_R_NO_FILENAME 111 356#define DSO_R_NO_FILENAME 111
357#define DSO_R_NO_FILE_SPECIFICATION 116
312#define DSO_R_NULL_HANDLE 104 358#define DSO_R_NULL_HANDLE 104
313#define DSO_R_SET_FILENAME_FAILED 112 359#define DSO_R_SET_FILENAME_FAILED 112
314#define DSO_R_STACK_ERROR 105 360#define DSO_R_STACK_ERROR 105
diff --git a/src/lib/libcrypto/dso/dso_dl.c b/src/lib/libcrypto/dso/dso_dl.c
index f7b4dfc0c3..417abb6ea9 100644
--- a/src/lib/libcrypto/dso/dso_dl.c
+++ b/src/lib/libcrypto/dso/dso_dl.c
@@ -1,4 +1,4 @@
1/* dso_dl.c */ 1/* dso_dl.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL 2/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -84,6 +84,7 @@ static int dl_finish(DSO *dso);
84static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg); 84static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
85#endif 85#endif
86static char *dl_name_converter(DSO *dso, const char *filename); 86static char *dl_name_converter(DSO *dso, const char *filename);
87static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
87 88
88static DSO_METHOD dso_meth_dl = { 89static DSO_METHOD dso_meth_dl = {
89 "OpenSSL 'dl' shared library method", 90 "OpenSSL 'dl' shared library method",
@@ -98,6 +99,7 @@ static DSO_METHOD dso_meth_dl = {
98#endif 99#endif
99 NULL, /* ctrl */ 100 NULL, /* ctrl */
100 dl_name_converter, 101 dl_name_converter,
102 dl_merger,
101 NULL, /* init */ 103 NULL, /* init */
102 NULL /* finish */ 104 NULL /* finish */
103 }; 105 };
@@ -239,6 +241,72 @@ static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
239 return((DSO_FUNC_TYPE)sym); 241 return((DSO_FUNC_TYPE)sym);
240 } 242 }
241 243
244static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
245 {
246 char *merged;
247
248 if(!filespec1 && !filespec2)
249 {
250 DSOerr(DSO_F_DL_MERGER,
251 ERR_R_PASSED_NULL_PARAMETER);
252 return(NULL);
253 }
254 /* If the first file specification is a rooted path, it rules.
255 same goes if the second file specification is missing. */
256 if (!filespec2 || filespec1[0] == '/')
257 {
258 merged = OPENSSL_malloc(strlen(filespec1) + 1);
259 if(!merged)
260 {
261 DSOerr(DSO_F_DL_MERGER,
262 ERR_R_MALLOC_FAILURE);
263 return(NULL);
264 }
265 strcpy(merged, filespec1);
266 }
267 /* If the first file specification is missing, the second one rules. */
268 else if (!filespec1)
269 {
270 merged = OPENSSL_malloc(strlen(filespec2) + 1);
271 if(!merged)
272 {
273 DSOerr(DSO_F_DL_MERGER,
274 ERR_R_MALLOC_FAILURE);
275 return(NULL);
276 }
277 strcpy(merged, filespec2);
278 }
279 else
280 /* This part isn't as trivial as it looks. It assumes that
281 the second file specification really is a directory, and
282 makes no checks whatsoever. Therefore, the result becomes
283 the concatenation of filespec2 followed by a slash followed
284 by filespec1. */
285 {
286 int spec2len, len;
287
288 spec2len = (filespec2 ? strlen(filespec2) : 0);
289 len = spec2len + (filespec1 ? strlen(filespec1) : 0);
290
291 if(filespec2 && filespec2[spec2len - 1] == '/')
292 {
293 spec2len--;
294 len--;
295 }
296 merged = OPENSSL_malloc(len + 2);
297 if(!merged)
298 {
299 DSOerr(DSO_F_DL_MERGER,
300 ERR_R_MALLOC_FAILURE);
301 return(NULL);
302 }
303 strcpy(merged, filespec2);
304 merged[spec2len] = '/';
305 strcpy(&merged[spec2len + 1], filespec1);
306 }
307 return(merged);
308 }
309
242/* This function is identical to the one in dso_dlfcn.c, but as it is highly 310/* This function is identical to the one in dso_dlfcn.c, but as it is highly
243 * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at the 311 * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at the
244 * same time, there's no great duplicating the code. Figuring out an elegant 312 * same time, there's no great duplicating the code. Figuring out an elegant
@@ -282,36 +350,4 @@ static char *dl_name_converter(DSO *dso, const char *filename)
282 return(translated); 350 return(translated);
283 } 351 }
284 352
285#ifdef OPENSSL_FIPS
286static void dl_ref_point(){}
287
288int DSO_pathbyaddr(void *addr,char *path,int sz)
289 {
290 struct shl_descriptor inf;
291 int i,len;
292
293 if (addr == NULL)
294 {
295 union { void(*f)(); void *p; } t = { dl_ref_point };
296 addr = t.p;
297 }
298
299 for (i=-1;shl_get_r(i,&inf)==0;i++)
300 {
301 if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
302 ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend))
303 {
304 len = (int)strlen(inf.filename);
305 if (sz <= 0) return len+1;
306 if (len >= sz) len=sz-1;
307 memcpy(path,inf.filename,len);
308 path[len++] = 0;
309 return len;
310 }
311 }
312
313 return -1;
314 }
315#endif
316
317#endif /* DSO_DL */ 353#endif /* DSO_DL */
diff --git a/src/lib/libcrypto/dso/dso_dlfcn.c b/src/lib/libcrypto/dso/dso_dlfcn.c
index d48b4202f2..f734c1c6b7 100644
--- a/src/lib/libcrypto/dso/dso_dlfcn.c
+++ b/src/lib/libcrypto/dso/dso_dlfcn.c
@@ -1,4 +1,4 @@
1/* dso_dlfcn.c */ 1/* dso_dlfcn.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL 2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -56,10 +56,6 @@
56 * 56 *
57 */ 57 */
58 58
59#ifdef __linux
60#define _GNU_SOURCE
61#endif
62
63#include <stdio.h> 59#include <stdio.h>
64#include "cryptlib.h" 60#include "cryptlib.h"
65#include <openssl/dso.h> 61#include <openssl/dso.h>
@@ -89,6 +85,8 @@ static int dlfcn_finish(DSO *dso);
89static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); 85static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
90#endif 86#endif
91static char *dlfcn_name_converter(DSO *dso, const char *filename); 87static char *dlfcn_name_converter(DSO *dso, const char *filename);
88static char *dlfcn_merger(DSO *dso, const char *filespec1,
89 const char *filespec2);
92 90
93static DSO_METHOD dso_meth_dlfcn = { 91static DSO_METHOD dso_meth_dlfcn = {
94 "OpenSSL 'dlfcn' shared library method", 92 "OpenSSL 'dlfcn' shared library method",
@@ -103,6 +101,7 @@ static DSO_METHOD dso_meth_dlfcn = {
103#endif 101#endif
104 NULL, /* ctrl */ 102 NULL, /* ctrl */
105 dlfcn_name_converter, 103 dlfcn_name_converter,
104 dlfcn_merger,
106 NULL, /* init */ 105 NULL, /* init */
107 NULL /* finish */ 106 NULL /* finish */
108 }; 107 };
@@ -145,13 +144,19 @@ static int dlfcn_load(DSO *dso)
145 void *ptr = NULL; 144 void *ptr = NULL;
146 /* See applicable comments in dso_dl.c */ 145 /* See applicable comments in dso_dl.c */
147 char *filename = DSO_convert_filename(dso, NULL); 146 char *filename = DSO_convert_filename(dso, NULL);
147 int flags = DLOPEN_FLAG;
148 148
149 if(filename == NULL) 149 if(filename == NULL)
150 { 150 {
151 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME); 151 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME);
152 goto err; 152 goto err;
153 } 153 }
154 ptr = dlopen(filename, DLOPEN_FLAG); 154
155#ifdef RTLD_GLOBAL
156 if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
157 flags |= RTLD_GLOBAL;
158#endif
159 ptr = dlopen(filename, flags);
155 if(ptr == NULL) 160 if(ptr == NULL)
156 { 161 {
157 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED); 162 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
@@ -250,7 +255,7 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
250 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE); 255 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
251 return(NULL); 256 return(NULL);
252 } 257 }
253 *(void**)(tsym) = dlsym(ptr, symname); 258 *(void **)(tsym) = dlsym(ptr, symname);
254 if(sym == NULL) 259 if(sym == NULL)
255 { 260 {
256 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE); 261 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
@@ -260,6 +265,73 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
260 return(sym); 265 return(sym);
261 } 266 }
262 267
268static char *dlfcn_merger(DSO *dso, const char *filespec1,
269 const char *filespec2)
270 {
271 char *merged;
272
273 if(!filespec1 && !filespec2)
274 {
275 DSOerr(DSO_F_DLFCN_MERGER,
276 ERR_R_PASSED_NULL_PARAMETER);
277 return(NULL);
278 }
279 /* If the first file specification is a rooted path, it rules.
280 same goes if the second file specification is missing. */
281 if (!filespec2 || filespec1[0] == '/')
282 {
283 merged = OPENSSL_malloc(strlen(filespec1) + 1);
284 if(!merged)
285 {
286 DSOerr(DSO_F_DLFCN_MERGER,
287 ERR_R_MALLOC_FAILURE);
288 return(NULL);
289 }
290 strcpy(merged, filespec1);
291 }
292 /* If the first file specification is missing, the second one rules. */
293 else if (!filespec1)
294 {
295 merged = OPENSSL_malloc(strlen(filespec2) + 1);
296 if(!merged)
297 {
298 DSOerr(DSO_F_DLFCN_MERGER,
299 ERR_R_MALLOC_FAILURE);
300 return(NULL);
301 }
302 strcpy(merged, filespec2);
303 }
304 else
305 /* This part isn't as trivial as it looks. It assumes that
306 the second file specification really is a directory, and
307 makes no checks whatsoever. Therefore, the result becomes
308 the concatenation of filespec2 followed by a slash followed
309 by filespec1. */
310 {
311 int spec2len, len;
312
313 spec2len = (filespec2 ? strlen(filespec2) : 0);
314 len = spec2len + (filespec1 ? strlen(filespec1) : 0);
315
316 if(filespec2 && filespec2[spec2len - 1] == '/')
317 {
318 spec2len--;
319 len--;
320 }
321 merged = OPENSSL_malloc(len + 2);
322 if(!merged)
323 {
324 DSOerr(DSO_F_DLFCN_MERGER,
325 ERR_R_MALLOC_FAILURE);
326 return(NULL);
327 }
328 strcpy(merged, filespec2);
329 merged[spec2len] = '/';
330 strcpy(&merged[spec2len + 1], filespec1);
331 }
332 return(merged);
333 }
334
263static char *dlfcn_name_converter(DSO *dso, const char *filename) 335static char *dlfcn_name_converter(DSO *dso, const char *filename)
264 { 336 {
265 char *translated; 337 char *translated;
@@ -294,32 +366,4 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
294 return(translated); 366 return(translated);
295 } 367 }
296 368
297#ifdef OPENSSL_FIPS
298static void dlfcn_ref_point(){}
299
300int DSO_pathbyaddr(void *addr,char *path,int sz)
301 {
302 Dl_info dli;
303 int len;
304
305 if (addr == NULL)
306 {
307 union { void(*f)(void); void *p; } t = { dlfcn_ref_point };
308 addr = t.p;
309 }
310
311 if (dladdr(addr,&dli))
312 {
313 len = (int)strlen(dli.dli_fname);
314 if (sz <= 0) return len+1;
315 if (len >= sz) len=sz-1;
316 memcpy(path,dli.dli_fname,len);
317 path[len++]=0;
318 return len;
319 }
320
321 ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
322 return -1;
323 }
324#endif
325#endif /* DSO_DLFCN */ 369#endif /* DSO_DLFCN */
diff --git a/src/lib/libcrypto/dso/dso_err.c b/src/lib/libcrypto/dso/dso_err.c
index 581677cc36..a8b0a210de 100644
--- a/src/lib/libcrypto/dso/dso_err.c
+++ b/src/lib/libcrypto/dso/dso_err.c
@@ -73,11 +73,13 @@ static ERR_STRING_DATA DSO_str_functs[]=
73{ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "DLFCN_BIND_FUNC"}, 73{ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "DLFCN_BIND_FUNC"},
74{ERR_FUNC(DSO_F_DLFCN_BIND_VAR), "DLFCN_BIND_VAR"}, 74{ERR_FUNC(DSO_F_DLFCN_BIND_VAR), "DLFCN_BIND_VAR"},
75{ERR_FUNC(DSO_F_DLFCN_LOAD), "DLFCN_LOAD"}, 75{ERR_FUNC(DSO_F_DLFCN_LOAD), "DLFCN_LOAD"},
76{ERR_FUNC(DSO_F_DLFCN_MERGER), "DLFCN_MERGER"},
76{ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER), "DLFCN_NAME_CONVERTER"}, 77{ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER), "DLFCN_NAME_CONVERTER"},
77{ERR_FUNC(DSO_F_DLFCN_UNLOAD), "DLFCN_UNLOAD"}, 78{ERR_FUNC(DSO_F_DLFCN_UNLOAD), "DLFCN_UNLOAD"},
78{ERR_FUNC(DSO_F_DL_BIND_FUNC), "DL_BIND_FUNC"}, 79{ERR_FUNC(DSO_F_DL_BIND_FUNC), "DL_BIND_FUNC"},
79{ERR_FUNC(DSO_F_DL_BIND_VAR), "DL_BIND_VAR"}, 80{ERR_FUNC(DSO_F_DL_BIND_VAR), "DL_BIND_VAR"},
80{ERR_FUNC(DSO_F_DL_LOAD), "DL_LOAD"}, 81{ERR_FUNC(DSO_F_DL_LOAD), "DL_LOAD"},
82{ERR_FUNC(DSO_F_DL_MERGER), "DL_MERGER"},
81{ERR_FUNC(DSO_F_DL_NAME_CONVERTER), "DL_NAME_CONVERTER"}, 83{ERR_FUNC(DSO_F_DL_NAME_CONVERTER), "DL_NAME_CONVERTER"},
82{ERR_FUNC(DSO_F_DL_UNLOAD), "DL_UNLOAD"}, 84{ERR_FUNC(DSO_F_DL_UNLOAD), "DL_UNLOAD"},
83{ERR_FUNC(DSO_F_DSO_BIND_FUNC), "DSO_bind_func"}, 85{ERR_FUNC(DSO_F_DSO_BIND_FUNC), "DSO_bind_func"},
@@ -88,17 +90,22 @@ static ERR_STRING_DATA DSO_str_functs[]=
88{ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"}, 90{ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"},
89{ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME), "DSO_get_loaded_filename"}, 91{ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME), "DSO_get_loaded_filename"},
90{ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"}, 92{ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"},
93{ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"},
91{ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"}, 94{ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"},
92{ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"}, 95{ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"},
93{ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER), "DSO_set_name_converter"}, 96{ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER), "DSO_set_name_converter"},
94{ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"}, 97{ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"},
95{ERR_FUNC(DSO_F_VMS_BIND_VAR), "VMS_BIND_VAR"}, 98{ERR_FUNC(DSO_F_VMS_BIND_SYM), "VMS_BIND_SYM"},
96{ERR_FUNC(DSO_F_VMS_LOAD), "VMS_LOAD"}, 99{ERR_FUNC(DSO_F_VMS_LOAD), "VMS_LOAD"},
100{ERR_FUNC(DSO_F_VMS_MERGER), "VMS_MERGER"},
97{ERR_FUNC(DSO_F_VMS_UNLOAD), "VMS_UNLOAD"}, 101{ERR_FUNC(DSO_F_VMS_UNLOAD), "VMS_UNLOAD"},
98{ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "WIN32_BIND_FUNC"}, 102{ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "WIN32_BIND_FUNC"},
99{ERR_FUNC(DSO_F_WIN32_BIND_VAR), "WIN32_BIND_VAR"}, 103{ERR_FUNC(DSO_F_WIN32_BIND_VAR), "WIN32_BIND_VAR"},
104{ERR_FUNC(DSO_F_WIN32_JOINER), "WIN32_JOINER"},
100{ERR_FUNC(DSO_F_WIN32_LOAD), "WIN32_LOAD"}, 105{ERR_FUNC(DSO_F_WIN32_LOAD), "WIN32_LOAD"},
106{ERR_FUNC(DSO_F_WIN32_MERGER), "WIN32_MERGER"},
101{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"}, 107{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"},
108{ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"},
102{ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"}, 109{ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"},
103{0,NULL} 110{0,NULL}
104 }; 111 };
@@ -107,11 +114,15 @@ static ERR_STRING_DATA DSO_str_reasons[]=
107 { 114 {
108{ERR_REASON(DSO_R_CTRL_FAILED) ,"control command failed"}, 115{ERR_REASON(DSO_R_CTRL_FAILED) ,"control command failed"},
109{ERR_REASON(DSO_R_DSO_ALREADY_LOADED) ,"dso already loaded"}, 116{ERR_REASON(DSO_R_DSO_ALREADY_LOADED) ,"dso already loaded"},
117{ERR_REASON(DSO_R_EMPTY_FILE_STRUCTURE) ,"empty file structure"},
118{ERR_REASON(DSO_R_FAILURE) ,"failure"},
110{ERR_REASON(DSO_R_FILENAME_TOO_BIG) ,"filename too big"}, 119{ERR_REASON(DSO_R_FILENAME_TOO_BIG) ,"filename too big"},
111{ERR_REASON(DSO_R_FINISH_FAILED) ,"cleanup method function failed"}, 120{ERR_REASON(DSO_R_FINISH_FAILED) ,"cleanup method function failed"},
121{ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX) ,"incorrect file syntax"},
112{ERR_REASON(DSO_R_LOAD_FAILED) ,"could not load the shared library"}, 122{ERR_REASON(DSO_R_LOAD_FAILED) ,"could not load the shared library"},
113{ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED),"name translation failed"}, 123{ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED),"name translation failed"},
114{ERR_REASON(DSO_R_NO_FILENAME) ,"no filename"}, 124{ERR_REASON(DSO_R_NO_FILENAME) ,"no filename"},
125{ERR_REASON(DSO_R_NO_FILE_SPECIFICATION) ,"no file specification"},
115{ERR_REASON(DSO_R_NULL_HANDLE) ,"a null shared library handle was used"}, 126{ERR_REASON(DSO_R_NULL_HANDLE) ,"a null shared library handle was used"},
116{ERR_REASON(DSO_R_SET_FILENAME_FAILED) ,"set filename failed"}, 127{ERR_REASON(DSO_R_SET_FILENAME_FAILED) ,"set filename failed"},
117{ERR_REASON(DSO_R_STACK_ERROR) ,"the meth_data stack is corrupt"}, 128{ERR_REASON(DSO_R_STACK_ERROR) ,"the meth_data stack is corrupt"},
@@ -125,15 +136,12 @@ static ERR_STRING_DATA DSO_str_reasons[]=
125 136
126void ERR_load_DSO_strings(void) 137void ERR_load_DSO_strings(void)
127 { 138 {
128 static int init=1; 139#ifndef OPENSSL_NO_ERR
129 140
130 if (init) 141 if (ERR_func_error_string(DSO_str_functs[0].error) == NULL)
131 { 142 {
132 init=0;
133#ifndef OPENSSL_NO_ERR
134 ERR_load_strings(0,DSO_str_functs); 143 ERR_load_strings(0,DSO_str_functs);
135 ERR_load_strings(0,DSO_str_reasons); 144 ERR_load_strings(0,DSO_str_reasons);
136#endif
137
138 } 145 }
146#endif
139 } 147 }
diff --git a/src/lib/libcrypto/dso/dso_lib.c b/src/lib/libcrypto/dso/dso_lib.c
index 48d9fdb25e..49bdd71309 100644
--- a/src/lib/libcrypto/dso/dso_lib.c
+++ b/src/lib/libcrypto/dso/dso_lib.c
@@ -1,4 +1,4 @@
1/* dso_lib.c */ 1/* dso_lib.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL 2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -390,6 +390,33 @@ int DSO_set_filename(DSO *dso, const char *filename)
390 return(1); 390 return(1);
391 } 391 }
392 392
393char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
394 {
395 char *result = NULL;
396
397 if(dso == NULL || filespec1 == NULL)
398 {
399 DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER);
400 return(NULL);
401 }
402 if(filespec1 == NULL)
403 filespec1 = dso->filename;
404 if(filespec1 == NULL)
405 {
406 DSOerr(DSO_F_DSO_MERGE,DSO_R_NO_FILE_SPECIFICATION);
407 return(NULL);
408 }
409 if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
410 {
411 if(dso->merger != NULL)
412 result = dso->merger(dso, filespec1, filespec2);
413 else if(dso->meth->dso_merger != NULL)
414 result = dso->meth->dso_merger(dso,
415 filespec1, filespec2);
416 }
417 return(result);
418 }
419
393char *DSO_convert_filename(DSO *dso, const char *filename) 420char *DSO_convert_filename(DSO *dso, const char *filename)
394 { 421 {
395 char *result = NULL; 422 char *result = NULL;
diff --git a/src/lib/libcrypto/dso/dso_null.c b/src/lib/libcrypto/dso/dso_null.c
index fa13a7cb0f..4972984651 100644
--- a/src/lib/libcrypto/dso/dso_null.c
+++ b/src/lib/libcrypto/dso/dso_null.c
@@ -75,6 +75,8 @@ static DSO_METHOD dso_meth_null = {
75 NULL, /* unbind_func */ 75 NULL, /* unbind_func */
76#endif 76#endif
77 NULL, /* ctrl */ 77 NULL, /* ctrl */
78 NULL, /* dso_name_converter */
79 NULL, /* dso_merger */
78 NULL, /* init */ 80 NULL, /* init */
79 NULL /* finish */ 81 NULL /* finish */
80 }; 82 };
diff --git a/src/lib/libcrypto/dso/dso_vms.c b/src/lib/libcrypto/dso/dso_vms.c
index 1674619d17..2c434ee8a6 100644
--- a/src/lib/libcrypto/dso/dso_vms.c
+++ b/src/lib/libcrypto/dso/dso_vms.c
@@ -1,4 +1,4 @@
1/* dso_vms.c */ 1/* dso_vms.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL 2/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -63,6 +63,7 @@
63#include <openssl/dso.h> 63#include <openssl/dso.h>
64#ifdef OPENSSL_SYS_VMS 64#ifdef OPENSSL_SYS_VMS
65#pragma message disable DOLLARID 65#pragma message disable DOLLARID
66#include <rms.h>
66#include <lib$routines.h> 67#include <lib$routines.h>
67#include <stsdef.h> 68#include <stsdef.h>
68#include <descrip.h> 69#include <descrip.h>
@@ -89,6 +90,8 @@ static int vms_finish(DSO *dso);
89static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg); 90static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg);
90#endif 91#endif
91static char *vms_name_converter(DSO *dso, const char *filename); 92static char *vms_name_converter(DSO *dso, const char *filename);
93static char *vms_merger(DSO *dso, const char *filespec1,
94 const char *filespec2);
92 95
93static DSO_METHOD dso_meth_vms = { 96static DSO_METHOD dso_meth_vms = {
94 "OpenSSL 'VMS' shared library method", 97 "OpenSSL 'VMS' shared library method",
@@ -103,6 +106,7 @@ static DSO_METHOD dso_meth_vms = {
103#endif 106#endif
104 NULL, /* ctrl */ 107 NULL, /* ctrl */
105 vms_name_converter, 108 vms_name_converter,
109 vms_merger,
106 NULL, /* init */ 110 NULL, /* init */
107 NULL /* finish */ 111 NULL /* finish */
108 }; 112 };
@@ -140,7 +144,7 @@ static int vms_load(DSO *dso)
140 144
141 if(filename == NULL) 145 if(filename == NULL)
142 { 146 {
143 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME); 147 DSOerr(DSO_F_VMS_LOAD,DSO_R_NO_FILENAME);
144 goto err; 148 goto err;
145 } 149 }
146 150
@@ -295,19 +299,19 @@ void vms_bind_sym(DSO *dso, const char *symname, void **sym)
295 299
296 if((dso == NULL) || (symname == NULL)) 300 if((dso == NULL) || (symname == NULL))
297 { 301 {
298 DSOerr(DSO_F_VMS_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); 302 DSOerr(DSO_F_VMS_BIND_SYM,ERR_R_PASSED_NULL_PARAMETER);
299 return; 303 return;
300 } 304 }
301 if(sk_num(dso->meth_data) < 1) 305 if(sk_num(dso->meth_data) < 1)
302 { 306 {
303 DSOerr(DSO_F_VMS_BIND_VAR,DSO_R_STACK_ERROR); 307 DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_STACK_ERROR);
304 return; 308 return;
305 } 309 }
306 ptr = (DSO_VMS_INTERNAL *)sk_value(dso->meth_data, 310 ptr = (DSO_VMS_INTERNAL *)sk_value(dso->meth_data,
307 sk_num(dso->meth_data) - 1); 311 sk_num(dso->meth_data) - 1);
308 if(ptr == NULL) 312 if(ptr == NULL)
309 { 313 {
310 DSOerr(DSO_F_VMS_BIND_VAR,DSO_R_NULL_HANDLE); 314 DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_NULL_HANDLE);
311 return; 315 return;
312 } 316 }
313 317
@@ -336,7 +340,7 @@ void vms_bind_sym(DSO *dso, const char *symname, void **sym)
336 { 340 {
337 errstring[length] = '\0'; 341 errstring[length] = '\0';
338 342
339 DSOerr(DSO_F_VMS_BIND_VAR,DSO_R_SYM_FAILURE); 343 DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_SYM_FAILURE);
340 if (ptr->imagename_dsc.dsc$w_length) 344 if (ptr->imagename_dsc.dsc$w_length)
341 ERR_add_error_data(9, 345 ERR_add_error_data(9,
342 "Symbol ", symname, 346 "Symbol ", symname,
@@ -368,6 +372,127 @@ static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname)
368 return sym; 372 return sym;
369 } 373 }
370 374
375static char *vms_merger(DSO *dso, const char *filespec1, const char *filespec2)
376 {
377 int status;
378 int filespec1len, filespec2len;
379 struct FAB fab;
380#ifdef NAML$C_MAXRSS
381 struct NAML nam;
382 char esa[NAML$C_MAXRSS];
383#else
384 struct NAM nam;
385 char esa[NAM$C_MAXRSS];
386#endif
387 char *merged;
388
389 if (!filespec1) filespec1 = "";
390 if (!filespec2) filespec2 = "";
391 filespec1len = strlen(filespec1);
392 filespec2len = strlen(filespec2);
393
394 fab = cc$rms_fab;
395#ifdef NAML$C_MAXRSS
396 nam = cc$rms_naml;
397#else
398 nam = cc$rms_nam;
399#endif
400
401 fab.fab$l_fna = (char *)filespec1;
402 fab.fab$b_fns = filespec1len;
403 fab.fab$l_dna = (char *)filespec2;
404 fab.fab$b_dns = filespec2len;
405#ifdef NAML$C_MAXRSS
406 if (filespec1len > NAM$C_MAXRSS)
407 {
408 fab.fab$l_fna = 0;
409 fab.fab$b_fns = 0;
410 nam.naml$l_long_filename = (char *)filespec1;
411 nam.naml$l_long_filename_size = filespec1len;
412 }
413 if (filespec2len > NAM$C_MAXRSS)
414 {
415 fab.fab$l_dna = 0;
416 fab.fab$b_dns = 0;
417 nam.naml$l_long_defname = (char *)filespec2;
418 nam.naml$l_long_defname_size = filespec2len;
419 }
420 nam.naml$l_esa = esa;
421 nam.naml$b_ess = NAM$C_MAXRSS;
422 nam.naml$l_long_expand = esa;
423 nam.naml$l_long_expand_alloc = sizeof(esa);
424 nam.naml$b_nop = NAM$M_SYNCHK | NAM$M_PWD;
425 nam.naml$v_no_short_upcase = 1;
426 fab.fab$l_naml = &nam;
427#else
428 nam.nam$l_esa = esa;
429 nam.nam$b_ess = NAM$C_MAXRSS;
430 nam.nam$b_nop = NAM$M_SYNCHK | NAM$M_PWD;
431 fab.fab$l_nam = &nam;
432#endif
433
434 status = sys$parse(&fab, 0, 0);
435
436 if(!$VMS_STATUS_SUCCESS(status))
437 {
438 unsigned short length;
439 char errstring[257];
440 struct dsc$descriptor_s errstring_dsc;
441
442 errstring_dsc.dsc$w_length = sizeof(errstring);
443 errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
444 errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
445 errstring_dsc.dsc$a_pointer = errstring;
446
447 status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
448
449 if (!$VMS_STATUS_SUCCESS(status))
450 lib$signal(status); /* This is really bad. Abort! */
451 else
452 {
453 errstring[length] = '\0';
454
455 DSOerr(DSO_F_VMS_MERGER,DSO_R_FAILURE);
456 ERR_add_error_data(7,
457 "filespec \"", filespec1, "\", ",
458 "defaults \"", filespec2, "\": ",
459 errstring);
460 }
461 return(NULL);
462 }
463#ifdef NAML$C_MAXRSS
464 if (nam.naml$l_long_expand_size)
465 {
466 merged = OPENSSL_malloc(nam.naml$l_long_expand_size + 1);
467 if(!merged)
468 goto malloc_err;
469 strncpy(merged, nam.naml$l_long_expand,
470 nam.naml$l_long_expand_size);
471 merged[nam.naml$l_long_expand_size] = '\0';
472 }
473 else
474 {
475 merged = OPENSSL_malloc(nam.naml$b_esl + 1);
476 if(!merged)
477 goto malloc_err;
478 strncpy(merged, nam.naml$l_esa,
479 nam.naml$b_esl);
480 merged[nam.naml$b_esl] = '\0';
481 }
482#else
483 merged = OPENSSL_malloc(nam.nam$b_esl + 1);
484 if(!merged)
485 goto malloc_err;
486 strncpy(merged, nam.nam$l_esa,
487 nam.nam$b_esl);
488 merged[nam.nam$b_esl] = '\0';
489#endif
490 return(merged);
491 malloc_err:
492 DSOerr(DSO_F_VMS_MERGER,
493 ERR_R_MALLOC_FAILURE);
494 }
495
371static char *vms_name_converter(DSO *dso, const char *filename) 496static char *vms_name_converter(DSO *dso, const char *filename)
372 { 497 {
373 int len = strlen(filename); 498 int len = strlen(filename);
diff --git a/src/lib/libcrypto/dso/dso_win32.c b/src/lib/libcrypto/dso/dso_win32.c
index cc4ac68696..fd3dd6a7fe 100644
--- a/src/lib/libcrypto/dso/dso_win32.c
+++ b/src/lib/libcrypto/dso/dso_win32.c
@@ -1,4 +1,4 @@
1/* dso_win32.c */ 1/* dso_win32.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL 2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -85,6 +85,26 @@ static FARPROC GetProcAddressA(HMODULE hModule,LPCSTR lpProcName)
85# endif 85# endif
86# undef GetProcAddress 86# undef GetProcAddress
87# define GetProcAddress GetProcAddressA 87# define GetProcAddress GetProcAddressA
88
89static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
90 {
91 WCHAR *fnamw;
92 size_t len_0=strlen(lpLibFileName)+1,i;
93
94#ifdef _MSC_VER
95 fnamw = (WCHAR *)_alloca (len_0*sizeof(WCHAR));
96#else
97 fnamw = (WCHAR *)alloca (len_0*sizeof(WCHAR));
98#endif
99 if (fnamw == NULL) return NULL;
100
101#if defined(_WIN32_WCE) && _WIN32_WCE>=101
102 if (!MultiByteToWideChar(CP_ACP,0,lpLibFileName,len_0,fnamw,len_0))
103#endif
104 for (i=0;i<len_0;i++) fnamw[i]=(WCHAR)lpLibFileName[i];
105
106 return LoadLibraryW(fnamw);
107 }
88#endif 108#endif
89 109
90/* Part of the hack in "win32_load" ... */ 110/* Part of the hack in "win32_load" ... */
@@ -102,6 +122,10 @@ static int win32_finish(DSO *dso);
102static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg); 122static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
103#endif 123#endif
104static char *win32_name_converter(DSO *dso, const char *filename); 124static char *win32_name_converter(DSO *dso, const char *filename);
125static char *win32_merger(DSO *dso, const char *filespec1,
126 const char *filespec2);
127
128static const char *openssl_strnchr(const char *string, int c, size_t len);
105 129
106static DSO_METHOD dso_meth_win32 = { 130static DSO_METHOD dso_meth_win32 = {
107 "OpenSSL 'win32' shared library method", 131 "OpenSSL 'win32' shared library method",
@@ -116,6 +140,7 @@ static DSO_METHOD dso_meth_win32 = {
116#endif 140#endif
117 NULL, /* ctrl */ 141 NULL, /* ctrl */
118 win32_name_converter, 142 win32_name_converter,
143 win32_merger,
119 NULL, /* init */ 144 NULL, /* init */
120 NULL /* finish */ 145 NULL /* finish */
121 }; 146 };
@@ -267,6 +292,330 @@ static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
267 return((DSO_FUNC_TYPE)sym); 292 return((DSO_FUNC_TYPE)sym);
268 } 293 }
269 294
295struct file_st
296 {
297 const char *node; int nodelen;
298 const char *device; int devicelen;
299 const char *predir; int predirlen;
300 const char *dir; int dirlen;
301 const char *file; int filelen;
302 };
303
304static struct file_st *win32_splitter(DSO *dso, const char *filename,
305 int assume_last_is_dir)
306 {
307 struct file_st *result = NULL;
308 enum { IN_NODE, IN_DEVICE, IN_FILE } position;
309 const char *start = filename;
310 char last;
311
312 if (!filename)
313 {
314 DSOerr(DSO_F_WIN32_SPLITTER,DSO_R_NO_FILENAME);
315 /*goto err;*/
316 return(NULL);
317 }
318
319 result = OPENSSL_malloc(sizeof(struct file_st));
320 if(result == NULL)
321 {
322 DSOerr(DSO_F_WIN32_SPLITTER,
323 ERR_R_MALLOC_FAILURE);
324 return(NULL);
325 }
326
327 memset(result, 0, sizeof(struct file_st));
328 position = IN_DEVICE;
329
330 if(filename[0] == '\\' && filename[1] == '\\'
331 || filename[0] == '/' && filename[1] == '/')
332 {
333 position = IN_NODE;
334 filename += 2;
335 start = filename;
336 result->node = start;
337 }
338
339 do
340 {
341 last = filename[0];
342 switch(last)
343 {
344 case ':':
345 if(position != IN_DEVICE)
346 {
347 DSOerr(DSO_F_WIN32_SPLITTER,
348 DSO_R_INCORRECT_FILE_SYNTAX);
349 /*goto err;*/
350 return(NULL);
351 }
352 result->device = start;
353 result->devicelen = filename - start;
354 position = IN_FILE;
355 start = ++filename;
356 result->dir = start;
357 break;
358 case '\\':
359 case '/':
360 if(position == IN_NODE)
361 {
362 result->nodelen = filename - start;
363 position = IN_FILE;
364 start = ++filename;
365 result->dir = start;
366 }
367 else if(position == IN_DEVICE)
368 {
369 position = IN_FILE;
370 filename++;
371 result->dir = start;
372 result->dirlen = filename - start;
373 start = filename;
374 }
375 else
376 {
377 filename++;
378 result->dirlen += filename - start;
379 start = filename;
380 }
381 break;
382 case '\0':
383 if(position == IN_NODE)
384 {
385 result->nodelen = filename - start;
386 }
387 else
388 {
389 if(filename - start > 0)
390 {
391 if (assume_last_is_dir)
392 {
393 if (position == IN_DEVICE)
394 {
395 result->dir = start;
396 result->dirlen = 0;
397 }
398 result->dirlen +=
399 filename - start;
400 }
401 else
402 {
403 result->file = start;
404 result->filelen =
405 filename - start;
406 }
407 }
408 }
409 break;
410 default:
411 filename++;
412 break;
413 }
414 }
415 while(last);
416
417 if(!result->nodelen) result->node = NULL;
418 if(!result->devicelen) result->device = NULL;
419 if(!result->dirlen) result->dir = NULL;
420 if(!result->filelen) result->file = NULL;
421
422 return(result);
423 }
424
425static char *win32_joiner(DSO *dso, const struct file_st *file_split)
426 {
427 int len = 0, offset = 0;
428 char *result = NULL;
429 const char *start;
430
431 if(!file_split)
432 {
433 DSOerr(DSO_F_WIN32_JOINER,
434 ERR_R_PASSED_NULL_PARAMETER);
435 return(NULL);
436 }
437 if(file_split->node)
438 {
439 len += 2 + file_split->nodelen; /* 2 for starting \\ */
440 if(file_split->predir || file_split->dir || file_split->file)
441 len++; /* 1 for ending \ */
442 }
443 else if(file_split->device)
444 {
445 len += file_split->devicelen + 1; /* 1 for ending : */
446 }
447 len += file_split->predirlen;
448 if(file_split->predir && (file_split->dir || file_split->file))
449 {
450 len++; /* 1 for ending \ */
451 }
452 len += file_split->dirlen;
453 if(file_split->dir && file_split->file)
454 {
455 len++; /* 1 for ending \ */
456 }
457 len += file_split->filelen;
458
459 if(!len)
460 {
461 DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE);
462 return(NULL);
463 }
464
465 result = OPENSSL_malloc(len + 1);
466 if (!result)
467 {
468 DSOerr(DSO_F_WIN32_JOINER,
469 ERR_R_MALLOC_FAILURE);
470 return(NULL);
471 }
472
473 if(file_split->node)
474 {
475 strcpy(&result[offset], "\\\\"); offset += 2;
476 strncpy(&result[offset], file_split->node,
477 file_split->nodelen); offset += file_split->nodelen;
478 if(file_split->predir || file_split->dir || file_split->file)
479 {
480 result[offset] = '\\'; offset++;
481 }
482 }
483 else if(file_split->device)
484 {
485 strncpy(&result[offset], file_split->device,
486 file_split->devicelen); offset += file_split->devicelen;
487 result[offset] = ':'; offset++;
488 }
489 start = file_split->predir;
490 while(file_split->predirlen > (start - file_split->predir))
491 {
492 const char *end = openssl_strnchr(start, '/',
493 file_split->predirlen - (start - file_split->predir));
494 if(!end)
495 end = start
496 + file_split->predirlen
497 - (start - file_split->predir);
498 strncpy(&result[offset], start,
499 end - start); offset += end - start;
500 result[offset] = '\\'; offset++;
501 start = end + 1;
502 }
503#if 0 /* Not needed, since the directory converter above already appeneded
504 a backslash */
505 if(file_split->predir && (file_split->dir || file_split->file))
506 {
507 result[offset] = '\\'; offset++;
508 }
509#endif
510 start = file_split->dir;
511 while(file_split->dirlen > (start - file_split->dir))
512 {
513 const char *end = openssl_strnchr(start, '/',
514 file_split->dirlen - (start - file_split->dir));
515 if(!end)
516 end = start
517 + file_split->dirlen
518 - (start - file_split->dir);
519 strncpy(&result[offset], start,
520 end - start); offset += end - start;
521 result[offset] = '\\'; offset++;
522 start = end + 1;
523 }
524#if 0 /* Not needed, since the directory converter above already appeneded
525 a backslash */
526 if(file_split->dir && file_split->file)
527 {
528 result[offset] = '\\'; offset++;
529 }
530#endif
531 strncpy(&result[offset], file_split->file,
532 file_split->filelen); offset += file_split->filelen;
533 result[offset] = '\0';
534 return(result);
535 }
536
537static char *win32_merger(DSO *dso, const char *filespec1, const char *filespec2)
538 {
539 char *merged = NULL;
540 struct file_st *filespec1_split = NULL;
541 struct file_st *filespec2_split = NULL;
542
543 if(!filespec1 && !filespec2)
544 {
545 DSOerr(DSO_F_WIN32_MERGER,
546 ERR_R_PASSED_NULL_PARAMETER);
547 return(NULL);
548 }
549 if (!filespec2)
550 {
551 merged = OPENSSL_malloc(strlen(filespec1) + 1);
552 if(!merged)
553 {
554 DSOerr(DSO_F_WIN32_MERGER,
555 ERR_R_MALLOC_FAILURE);
556 return(NULL);
557 }
558 strcpy(merged, filespec1);
559 }
560 else if (!filespec1)
561 {
562 merged = OPENSSL_malloc(strlen(filespec2) + 1);
563 if(!merged)
564 {
565 DSOerr(DSO_F_WIN32_MERGER,
566 ERR_R_MALLOC_FAILURE);
567 return(NULL);
568 }
569 strcpy(merged, filespec2);
570 }
571 else
572 {
573 filespec1_split = win32_splitter(dso, filespec1, 0);
574 if (!filespec1_split)
575 {
576 DSOerr(DSO_F_WIN32_MERGER,
577 ERR_R_MALLOC_FAILURE);
578 return(NULL);
579 }
580 filespec2_split = win32_splitter(dso, filespec2, 1);
581 if (!filespec2_split)
582 {
583 DSOerr(DSO_F_WIN32_MERGER,
584 ERR_R_MALLOC_FAILURE);
585 OPENSSL_free(filespec1_split);
586 return(NULL);
587 }
588
589 /* Fill in into filespec1_split */
590 if (!filespec1_split->node && !filespec1_split->device)
591 {
592 filespec1_split->node = filespec2_split->node;
593 filespec1_split->nodelen = filespec2_split->nodelen;
594 filespec1_split->device = filespec2_split->device;
595 filespec1_split->devicelen = filespec2_split->devicelen;
596 }
597 if (!filespec1_split->dir)
598 {
599 filespec1_split->dir = filespec2_split->dir;
600 filespec1_split->dirlen = filespec2_split->dirlen;
601 }
602 else if (filespec1_split->dir[0] != '\\'
603 && filespec1_split->dir[0] != '/')
604 {
605 filespec1_split->predir = filespec2_split->dir;
606 filespec1_split->predirlen = filespec2_split->dirlen;
607 }
608 if (!filespec1_split->file)
609 {
610 filespec1_split->file = filespec2_split->file;
611 filespec1_split->filelen = filespec2_split->filelen;
612 }
613
614 merged = win32_joiner(dso, filespec1_split);
615 }
616 return(merged);
617 }
618
270static char *win32_name_converter(DSO *dso, const char *filename) 619static char *win32_name_converter(DSO *dso, const char *filename)
271 { 620 {
272 char *translated; 621 char *translated;
@@ -295,4 +644,17 @@ static char *win32_name_converter(DSO *dso, const char *filename)
295 return(translated); 644 return(translated);
296 } 645 }
297 646
647static const char *openssl_strnchr(const char *string, int c, size_t len)
648 {
649 size_t i;
650 const char *p;
651 for (i = 0, p = string; i < len && *p; i++, p++)
652 {
653 if (*p == c)
654 return p;
655 }
656 return NULL;
657 }
658
659
298#endif /* OPENSSL_SYS_WIN32 */ 660#endif /* OPENSSL_SYS_WIN32 */