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/Makefile150
-rw-r--r--src/lib/libcrypto/dso/README22
-rw-r--r--src/lib/libcrypto/dso/dso_beos.c270
-rw-r--r--src/lib/libcrypto/dso/dso_dl.c395
-rw-r--r--src/lib/libcrypto/dso/dso_dlfcn.c24
-rw-r--r--src/lib/libcrypto/dso/dso_vms.c525
-rw-r--r--src/lib/libcrypto/dso/dso_win32.c844
7 files changed, 2219 insertions, 11 deletions
diff --git a/src/lib/libcrypto/dso/Makefile b/src/lib/libcrypto/dso/Makefile
new file mode 100644
index 0000000000..fb2709ed63
--- /dev/null
+++ b/src/lib/libcrypto/dso/Makefile
@@ -0,0 +1,150 @@
1#
2# OpenSSL/crypto/dso/Makefile
3#
4
5DIR= dso
6TOP= ../..
7CC= cc
8INCLUDES= -I.. -I$(TOP) -I../../include
9CFLAG=-g
10MAKEFILE= Makefile
11AR= ar r
12
13CFLAGS= $(INCLUDES) $(CFLAG)
14
15GENERAL=Makefile
16TEST=
17APPS=
18
19LIB=$(TOP)/libcrypto.a
20LIBSRC= dso_dl.c dso_dlfcn.c dso_err.c dso_lib.c dso_null.c \
21 dso_openssl.c dso_win32.c dso_vms.c dso_beos.c
22LIBOBJ= dso_dl.o dso_dlfcn.o dso_err.o dso_lib.o dso_null.o \
23 dso_openssl.o dso_win32.o dso_vms.o dso_beos.o
24
25SRC= $(LIBSRC)
26
27EXHEADER= dso.h
28HEADER= $(EXHEADER)
29
30ALL= $(GENERAL) $(SRC) $(HEADER)
31
32top:
33 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
34
35all: lib
36
37lib: $(LIBOBJ)
38 $(AR) $(LIB) $(LIBOBJ)
39 $(RANLIB) $(LIB) || echo Never mind.
40 @touch lib
41
42files:
43 $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
44
45links:
46 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
47 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
48 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
49
50install:
51 @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
52 @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
53 do \
54 (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
55 chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
56 done;
57
58tags:
59 ctags $(SRC)
60
61tests:
62
63lint:
64 lint -DLINT $(INCLUDES) $(SRC)>fluff
65
66depend:
67 @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
68 $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
69
70dclean:
71 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
72 mv -f Makefile.new $(MAKEFILE)
73
74clean:
75 rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
76
77# DO NOT DELETE THIS LINE -- make depend depends on it.
78
79dso_beos.o: ../../e_os.h ../../include/openssl/bio.h
80dso_beos.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
81dso_beos.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
82dso_beos.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
83dso_beos.o: ../../include/openssl/opensslconf.h
84dso_beos.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
85dso_beos.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
86dso_beos.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_beos.c
87dso_dl.o: ../../e_os.h ../../include/openssl/bio.h
88dso_dl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
89dso_dl.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
90dso_dl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
91dso_dl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
92dso_dl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
93dso_dl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
94dso_dl.o: ../cryptlib.h dso_dl.c
95dso_dlfcn.o: ../../e_os.h ../../include/openssl/bio.h
96dso_dlfcn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
97dso_dlfcn.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
98dso_dlfcn.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
99dso_dlfcn.o: ../../include/openssl/opensslconf.h
100dso_dlfcn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
101dso_dlfcn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
102dso_dlfcn.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_dlfcn.c
103dso_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
104dso_err.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
105dso_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
106dso_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
107dso_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
108dso_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
109dso_err.o: dso_err.c
110dso_lib.o: ../../e_os.h ../../include/openssl/bio.h
111dso_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
112dso_lib.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
113dso_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
114dso_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
115dso_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
116dso_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
117dso_lib.o: ../cryptlib.h dso_lib.c
118dso_null.o: ../../e_os.h ../../include/openssl/bio.h
119dso_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
120dso_null.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
121dso_null.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
122dso_null.o: ../../include/openssl/opensslconf.h
123dso_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
124dso_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
125dso_null.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_null.c
126dso_openssl.o: ../../e_os.h ../../include/openssl/bio.h
127dso_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
128dso_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
129dso_openssl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
130dso_openssl.o: ../../include/openssl/opensslconf.h
131dso_openssl.o: ../../include/openssl/opensslv.h
132dso_openssl.o: ../../include/openssl/ossl_typ.h
133dso_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
134dso_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_openssl.c
135dso_vms.o: ../../e_os.h ../../include/openssl/bio.h
136dso_vms.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
137dso_vms.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
138dso_vms.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
139dso_vms.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
140dso_vms.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
141dso_vms.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
142dso_vms.o: ../cryptlib.h dso_vms.c
143dso_win32.o: ../../e_os.h ../../include/openssl/bio.h
144dso_win32.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
145dso_win32.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
146dso_win32.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
147dso_win32.o: ../../include/openssl/opensslconf.h
148dso_win32.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
149dso_win32.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
150dso_win32.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_win32.c
diff --git a/src/lib/libcrypto/dso/README b/src/lib/libcrypto/dso/README
new file mode 100644
index 0000000000..d0bc9a89fb
--- /dev/null
+++ b/src/lib/libcrypto/dso/README
@@ -0,0 +1,22 @@
1NOTES
2-----
3
4I've checked out HPUX (well, version 11 at least) and shl_t is
5a pointer type so it's safe to use in the way it has been in
6dso_dl.c. On the other hand, HPUX11 support dlfcn too and
7according to their man page, prefer developers to move to that.
8I'll leave Richard's changes there as I guess dso_dl is needed
9for HPUX10.20.
10
11There is now a callback scheme in place where filename conversion can
12(a) be turned off altogether through the use of the
13 DSO_FLAG_NO_NAME_TRANSLATION flag,
14(b) be handled by default using the default DSO_METHOD's converter
15(c) overriden per-DSO by setting the override callback
16(d) a mix of (b) and (c) - eg. implement an override callback that;
17 (i) checks if we're win32 (if(strstr(dso->meth->name, "win32")....)
18 and if so, convert "blah" into "blah32.dll" (the default is
19 otherwise to make it "blah.dll").
20 (ii) default to the normal behaviour - we're not on win32, eg.
21 finish with (return dso->meth->dso_name_converter(dso,NULL)).
22
diff --git a/src/lib/libcrypto/dso/dso_beos.c b/src/lib/libcrypto/dso/dso_beos.c
new file mode 100644
index 0000000000..553966e699
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_beos.c
@@ -0,0 +1,270 @@
1/* dso_beos.c */
2/* Written by Marcin Konicki (ahwayakchih@neoni.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61#include "cryptlib.h"
62#include <openssl/dso.h>
63
64#if !defined(OPENSSL_SYS_BEOS)
65DSO_METHOD *DSO_METHOD_beos(void)
66 {
67 return NULL;
68 }
69#else
70
71#include <kernel/image.h>
72
73static int beos_load(DSO *dso);
74static int beos_unload(DSO *dso);
75static void *beos_bind_var(DSO *dso, const char *symname);
76static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname);
77#if 0
78static int beos_unbind_var(DSO *dso, char *symname, void *symptr);
79static int beos_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
80static int beos_init(DSO *dso);
81static int beos_finish(DSO *dso);
82static long beos_ctrl(DSO *dso, int cmd, long larg, void *parg);
83#endif
84static char *beos_name_converter(DSO *dso, const char *filename);
85
86static DSO_METHOD dso_meth_beos = {
87 "OpenSSL 'beos' shared library method",
88 beos_load,
89 beos_unload,
90 beos_bind_var,
91 beos_bind_func,
92/* For now, "unbind" doesn't exist */
93#if 0
94 NULL, /* unbind_var */
95 NULL, /* unbind_func */
96#endif
97 NULL, /* ctrl */
98 beos_name_converter,
99 NULL, /* init */
100 NULL /* finish */
101 };
102
103DSO_METHOD *DSO_METHOD_beos(void)
104 {
105 return(&dso_meth_beos);
106 }
107
108/* For this DSO_METHOD, our meth_data STACK will contain;
109 * (i) a pointer to the handle (image_id) returned from
110 * load_add_on().
111 */
112
113static int beos_load(DSO *dso)
114 {
115 image_id id;
116 /* See applicable comments from dso_dl.c */
117 char *filename = DSO_convert_filename(dso, NULL);
118
119 if(filename == NULL)
120 {
121 DSOerr(DSO_F_BEOS_LOAD,DSO_R_NO_FILENAME);
122 goto err;
123 }
124 id = load_add_on(filename);
125 if(id < 1)
126 {
127 DSOerr(DSO_F_BEOS_LOAD,DSO_R_LOAD_FAILED);
128 ERR_add_error_data(3, "filename(", filename, ")");
129 goto err;
130 }
131 if(!sk_push(dso->meth_data, (char *)id))
132 {
133 DSOerr(DSO_F_BEOS_LOAD,DSO_R_STACK_ERROR);
134 goto err;
135 }
136 /* Success */
137 dso->loaded_filename = filename;
138 return(1);
139err:
140 /* Cleanup !*/
141 if(filename != NULL)
142 OPENSSL_free(filename);
143 if(id > 0)
144 unload_add_on(id);
145 return(0);
146 }
147
148static int beos_unload(DSO *dso)
149 {
150 image_id id;
151 if(dso == NULL)
152 {
153 DSOerr(DSO_F_BEOS_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
154 return(0);
155 }
156 if(sk_num(dso->meth_data) < 1)
157 return(1);
158 id = (image_id)sk_pop(dso->meth_data);
159 if(id < 1)
160 {
161 DSOerr(DSO_F_BEOS_UNLOAD,DSO_R_NULL_HANDLE);
162 return(0);
163 }
164 if(unload_add_on(id) != B_OK)
165 {
166 DSOerr(DSO_F_BEOS_UNLOAD,DSO_R_UNLOAD_FAILED);
167 /* We should push the value back onto the stack in
168 * case of a retry. */
169 sk_push(dso->meth_data, (char *)id);
170 return(0);
171 }
172 return(1);
173 }
174
175static void *beos_bind_var(DSO *dso, const char *symname)
176 {
177 image_id id;
178 void *sym;
179
180 if((dso == NULL) || (symname == NULL))
181 {
182 DSOerr(DSO_F_BEOS_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
183 return(NULL);
184 }
185 if(sk_num(dso->meth_data) < 1)
186 {
187 DSOerr(DSO_F_BEOS_BIND_VAR,DSO_R_STACK_ERROR);
188 return(NULL);
189 }
190 id = (image_id)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
191 if(id < 1)
192 {
193 DSOerr(DSO_F_BEOS_BIND_VAR,DSO_R_NULL_HANDLE);
194 return(NULL);
195 }
196 if(get_image_symbol(id, symname, B_SYMBOL_TYPE_DATA, &sym) != B_OK)
197 {
198 DSOerr(DSO_F_BEOS_BIND_VAR,DSO_R_SYM_FAILURE);
199 ERR_add_error_data(3, "symname(", symname, ")");
200 return(NULL);
201 }
202 return(sym);
203 }
204
205static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname)
206 {
207 image_id id;
208 void *sym;
209
210 if((dso == NULL) || (symname == NULL))
211 {
212 DSOerr(DSO_F_BEOS_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
213 return(NULL);
214 }
215 if(sk_num(dso->meth_data) < 1)
216 {
217 DSOerr(DSO_F_BEOS_BIND_FUNC,DSO_R_STACK_ERROR);
218 return(NULL);
219 }
220 id = (image_id)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
221 if(id < 1)
222 {
223 DSOerr(DSO_F_BEOS_BIND_FUNC,DSO_R_NULL_HANDLE);
224 return(NULL);
225 }
226 if(get_image_symbol(id, symname, B_SYMBOL_TYPE_TEXT, &sym) != B_OK)
227 {
228 DSOerr(DSO_F_BEOS_BIND_FUNC,DSO_R_SYM_FAILURE);
229 ERR_add_error_data(3, "symname(", symname, ")");
230 return(NULL);
231 }
232 return((DSO_FUNC_TYPE)sym);
233 }
234
235/* This one is the same as the one in dlfcn */
236static char *beos_name_converter(DSO *dso, const char *filename)
237 {
238 char *translated;
239 int len, rsize, transform;
240
241 len = strlen(filename);
242 rsize = len + 1;
243 transform = (strstr(filename, "/") == NULL);
244 if(transform)
245 {
246 /* We will convert this to "%s.so" or "lib%s.so" */
247 rsize += 3; /* The length of ".so" */
248 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
249 rsize += 3; /* The length of "lib" */
250 }
251 translated = OPENSSL_malloc(rsize);
252 if(translated == NULL)
253 {
254 DSOerr(DSO_F_BEOS_NAME_CONVERTER,
255 DSO_R_NAME_TRANSLATION_FAILED);
256 return(NULL);
257 }
258 if(transform)
259 {
260 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
261 sprintf(translated, "lib%s.so", filename);
262 else
263 sprintf(translated, "%s.so", filename);
264 }
265 else
266 sprintf(translated, "%s", filename);
267 return(translated);
268 }
269
270#endif
diff --git a/src/lib/libcrypto/dso/dso_dl.c b/src/lib/libcrypto/dso/dso_dl.c
new file mode 100644
index 0000000000..c3b4f6cf45
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_dl.c
@@ -0,0 +1,395 @@
1/* dso_dl.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/dso.h>
62
63#ifndef DSO_DL
64DSO_METHOD *DSO_METHOD_dl(void)
65 {
66 return NULL;
67 }
68#else
69
70#include <dl.h>
71
72/* Part of the hack in "dl_load" ... */
73#define DSO_MAX_TRANSLATED_SIZE 256
74
75static int dl_load(DSO *dso);
76static int dl_unload(DSO *dso);
77static void *dl_bind_var(DSO *dso, const char *symname);
78static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname);
79#if 0
80static int dl_unbind_var(DSO *dso, char *symname, void *symptr);
81static int dl_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
82static int dl_init(DSO *dso);
83static int dl_finish(DSO *dso);
84static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
85#endif
86static char *dl_name_converter(DSO *dso, const char *filename);
87static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
88static int dl_pathbyaddr(void *addr,char *path,int sz);
89static void *dl_globallookup(const char *name);
90
91static DSO_METHOD dso_meth_dl = {
92 "OpenSSL 'dl' shared library method",
93 dl_load,
94 dl_unload,
95 dl_bind_var,
96 dl_bind_func,
97/* For now, "unbind" doesn't exist */
98#if 0
99 NULL, /* unbind_var */
100 NULL, /* unbind_func */
101#endif
102 NULL, /* ctrl */
103 dl_name_converter,
104 dl_merger,
105 NULL, /* init */
106 NULL, /* finish */
107 dl_pathbyaddr,
108 dl_globallookup
109 };
110
111DSO_METHOD *DSO_METHOD_dl(void)
112 {
113 return(&dso_meth_dl);
114 }
115
116/* For this DSO_METHOD, our meth_data STACK will contain;
117 * (i) the handle (shl_t) returned from shl_load().
118 * NB: I checked on HPUX11 and shl_t is itself a pointer
119 * type so the cast is safe.
120 */
121
122static int dl_load(DSO *dso)
123 {
124 shl_t ptr = NULL;
125 /* We don't do any fancy retries or anything, just take the method's
126 * (or DSO's if it has the callback set) best translation of the
127 * platform-independant filename and try once with that. */
128 char *filename= DSO_convert_filename(dso, NULL);
129
130 if(filename == NULL)
131 {
132 DSOerr(DSO_F_DL_LOAD,DSO_R_NO_FILENAME);
133 goto err;
134 }
135 ptr = shl_load(filename, BIND_IMMEDIATE |
136 (dso->flags&DSO_FLAG_NO_NAME_TRANSLATION?0:DYNAMIC_PATH), 0L);
137 if(ptr == NULL)
138 {
139 DSOerr(DSO_F_DL_LOAD,DSO_R_LOAD_FAILED);
140 ERR_add_error_data(4, "filename(", filename, "): ",
141 strerror(errno));
142 goto err;
143 }
144 if(!sk_push(dso->meth_data, (char *)ptr))
145 {
146 DSOerr(DSO_F_DL_LOAD,DSO_R_STACK_ERROR);
147 goto err;
148 }
149 /* Success, stick the converted filename we've loaded under into the DSO
150 * (it also serves as the indicator that we are currently loaded). */
151 dso->loaded_filename = filename;
152 return(1);
153err:
154 /* Cleanup! */
155 if(filename != NULL)
156 OPENSSL_free(filename);
157 if(ptr != NULL)
158 shl_unload(ptr);
159 return(0);
160 }
161
162static int dl_unload(DSO *dso)
163 {
164 shl_t ptr;
165 if(dso == NULL)
166 {
167 DSOerr(DSO_F_DL_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
168 return(0);
169 }
170 if(sk_num(dso->meth_data) < 1)
171 return(1);
172 /* Is this statement legal? */
173 ptr = (shl_t)sk_pop(dso->meth_data);
174 if(ptr == NULL)
175 {
176 DSOerr(DSO_F_DL_UNLOAD,DSO_R_NULL_HANDLE);
177 /* Should push the value back onto the stack in
178 * case of a retry. */
179 sk_push(dso->meth_data, (char *)ptr);
180 return(0);
181 }
182 shl_unload(ptr);
183 return(1);
184 }
185
186static void *dl_bind_var(DSO *dso, const char *symname)
187 {
188 shl_t ptr;
189 void *sym;
190
191 if((dso == NULL) || (symname == NULL))
192 {
193 DSOerr(DSO_F_DL_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
194 return(NULL);
195 }
196 if(sk_num(dso->meth_data) < 1)
197 {
198 DSOerr(DSO_F_DL_BIND_VAR,DSO_R_STACK_ERROR);
199 return(NULL);
200 }
201 ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
202 if(ptr == NULL)
203 {
204 DSOerr(DSO_F_DL_BIND_VAR,DSO_R_NULL_HANDLE);
205 return(NULL);
206 }
207 if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0)
208 {
209 DSOerr(DSO_F_DL_BIND_VAR,DSO_R_SYM_FAILURE);
210 ERR_add_error_data(4, "symname(", symname, "): ",
211 strerror(errno));
212 return(NULL);
213 }
214 return(sym);
215 }
216
217static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
218 {
219 shl_t ptr;
220 void *sym;
221
222 if((dso == NULL) || (symname == NULL))
223 {
224 DSOerr(DSO_F_DL_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
225 return(NULL);
226 }
227 if(sk_num(dso->meth_data) < 1)
228 {
229 DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_STACK_ERROR);
230 return(NULL);
231 }
232 ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
233 if(ptr == NULL)
234 {
235 DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_NULL_HANDLE);
236 return(NULL);
237 }
238 if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0)
239 {
240 DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_SYM_FAILURE);
241 ERR_add_error_data(4, "symname(", symname, "): ",
242 strerror(errno));
243 return(NULL);
244 }
245 return((DSO_FUNC_TYPE)sym);
246 }
247
248static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
249 {
250 char *merged;
251
252 if(!filespec1 && !filespec2)
253 {
254 DSOerr(DSO_F_DL_MERGER,
255 ERR_R_PASSED_NULL_PARAMETER);
256 return(NULL);
257 }
258 /* If the first file specification is a rooted path, it rules.
259 same goes if the second file specification is missing. */
260 if (!filespec2 || filespec1[0] == '/')
261 {
262 size_t len = strlen(filespec1) + 1;
263 merged = OPENSSL_malloc(len);
264 if(!merged)
265 {
266 DSOerr(DSO_F_DL_MERGER,
267 ERR_R_MALLOC_FAILURE);
268 return(NULL);
269 }
270 memcpy(merged, filespec1, len);
271 }
272 /* If the first file specification is missing, the second one rules. */
273 else if (!filespec1)
274 {
275 size_t len = strlen(filespec2) + 1;
276 merged = OPENSSL_malloc(strlen(filespec2) + 1);
277 if(!merged)
278 {
279 DSOerr(DSO_F_DL_MERGER,
280 ERR_R_MALLOC_FAILURE);
281 return(NULL);
282 }
283 memcpy(merged, filespec2, len);
284 }
285 else
286 /* This part isn't as trivial as it looks. It assumes that
287 the second file specification really is a directory, and
288 makes no checks whatsoever. Therefore, the result becomes
289 the concatenation of filespec2 followed by a slash followed
290 by filespec1. */
291 {
292 size_t spec2len, len;
293
294 spec2len = (filespec2 ? strlen(filespec2) : 0);
295 len = spec2len + (filespec1 ? strlen(filespec1) : 0);
296
297 if(filespec2 && filespec2[spec2len - 1] == '/')
298 {
299 spec2len--;
300 len--;
301 }
302 merged = OPENSSL_malloc(len + 2);
303 if(!merged)
304 {
305 DSOerr(DSO_F_DL_MERGER,
306 ERR_R_MALLOC_FAILURE);
307 return(NULL);
308 }
309 strlcpy(merged, filespec2, len + 2);
310 merged[spec2len] = '/';
311 strlcpy(&merged[spec2len + 1], filespec1, 1 + len - spec2len);
312 }
313 return(merged);
314 }
315
316/* This function is identical to the one in dso_dlfcn.c, but as it is highly
317 * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at the
318 * same time, there's no great duplicating the code. Figuring out an elegant
319 * way to share one copy of the code would be more difficult and would not
320 * leave the implementations independant. */
321#if defined(__hpux)
322static const char extension[] = ".sl";
323#else
324static const char extension[] = ".so";
325#endif
326static char *dl_name_converter(DSO *dso, const char *filename)
327 {
328 char *translated;
329 int len, rsize, transform;
330
331 len = strlen(filename);
332 rsize = len + 1;
333 transform = (strstr(filename, "/") == NULL);
334 {
335 /* We will convert this to "%s.s?" or "lib%s.s?" */
336 rsize += strlen(extension);/* The length of ".s?" */
337 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
338 rsize += 3; /* The length of "lib" */
339 }
340 translated = OPENSSL_malloc(rsize);
341 if(translated == NULL)
342 {
343 DSOerr(DSO_F_DL_NAME_CONVERTER,
344 DSO_R_NAME_TRANSLATION_FAILED);
345 return(NULL);
346 }
347 if(transform)
348 {
349 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
350 sprintf(translated, "lib%s%s", filename, extension);
351 else
352 sprintf(translated, "%s%s", filename, extension);
353 }
354 else
355 sprintf(translated, "%s", filename);
356 return(translated);
357 }
358
359static int dl_pathbyaddr(void *addr,char *path,int sz)
360 {
361 struct shl_descriptor inf;
362 int i,len;
363
364 if (addr == NULL)
365 {
366 union { int(*f)(void*,char*,int); void *p; } t =
367 { dl_pathbyaddr };
368 addr = t.p;
369 }
370
371 for (i=-1;shl_get_r(i,&inf)==0;i++)
372 {
373 if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
374 ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend))
375 {
376 len = (int)strlen(inf.filename);
377 if (sz <= 0) return len+1;
378 if (len >= sz) len=sz-1;
379 memcpy(path,inf.filename,len);
380 path[len++] = 0;
381 return len;
382 }
383 }
384
385 return -1;
386 }
387
388static void *dl_globallookup(const char *name)
389 {
390 void *ret;
391 shl_t h = NULL;
392
393 return shl_findsym(&h,name,TYPE_UNDEFINED,&ret) ? NULL : ret;
394 }
395#endif /* DSO_DL */
diff --git a/src/lib/libcrypto/dso/dso_dlfcn.c b/src/lib/libcrypto/dso/dso_dlfcn.c
index 5f2254806c..e78004903c 100644
--- a/src/lib/libcrypto/dso/dso_dlfcn.c
+++ b/src/lib/libcrypto/dso/dso_dlfcn.c
@@ -86,8 +86,7 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
86# if defined(_AIX) || defined(__CYGWIN__) || \ 86# if defined(_AIX) || defined(__CYGWIN__) || \
87 defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ 87 defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
88 (defined(__osf__) && !defined(RTLD_NEXT)) || \ 88 (defined(__osf__) && !defined(RTLD_NEXT)) || \
89 (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \ 89 (defined(__OpenBSD__) && (!defined(__ELF__) || !defined(RTLD_SELF)))
90 defined(__ANDROID__)
91# undef HAVE_DLINFO 90# undef HAVE_DLINFO
92# endif 91# endif
93#endif 92#endif
@@ -297,6 +296,7 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1,
297 const char *filespec2) 296 const char *filespec2)
298 { 297 {
299 char *merged; 298 char *merged;
299 size_t len;
300 300
301 if(!filespec1 && !filespec2) 301 if(!filespec1 && !filespec2)
302 { 302 {
@@ -308,17 +308,19 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1,
308 same goes if the second file specification is missing. */ 308 same goes if the second file specification is missing. */
309 if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) 309 if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/'))
310 { 310 {
311 merged = OPENSSL_malloc(strlen(filespec1) + 1); 311 len = strlen(filespec1) + 1;
312 merged = OPENSSL_malloc(len);
312 if(!merged) 313 if(!merged)
313 { 314 {
314 DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); 315 DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
315 return(NULL); 316 return(NULL);
316 } 317 }
317 strcpy(merged, filespec1); 318 strlcpy(merged, filespec1, len);
318 } 319 }
319 /* If the first file specification is missing, the second one rules. */ 320 /* If the first file specification is missing, the second one rules. */
320 else if (!filespec1) 321 else if (!filespec1)
321 { 322 {
323 len = strlen(filespec2) + 1;
322 merged = OPENSSL_malloc(strlen(filespec2) + 1); 324 merged = OPENSSL_malloc(strlen(filespec2) + 1);
323 if(!merged) 325 if(!merged)
324 { 326 {
@@ -326,7 +328,7 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1,
326 ERR_R_MALLOC_FAILURE); 328 ERR_R_MALLOC_FAILURE);
327 return(NULL); 329 return(NULL);
328 } 330 }
329 strcpy(merged, filespec2); 331 strlcpy(merged, filespec2, len);
330 } 332 }
331 else 333 else
332 /* This part isn't as trivial as it looks. It assumes that 334 /* This part isn't as trivial as it looks. It assumes that
@@ -352,9 +354,9 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1,
352 ERR_R_MALLOC_FAILURE); 354 ERR_R_MALLOC_FAILURE);
353 return(NULL); 355 return(NULL);
354 } 356 }
355 strcpy(merged, filespec2); 357 strlcpy(merged, filespec2, len + 2);
356 merged[spec2len] = '/'; 358 merged[spec2len] = '/';
357 strcpy(&merged[spec2len + 1], filespec1); 359 strlcpy(&merged[spec2len + 1], filespec1, len + 1 - spec2len);
358 } 360 }
359 return(merged); 361 return(merged);
360 } 362 }
@@ -393,16 +395,16 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
393 if(transform) 395 if(transform)
394 { 396 {
395 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) 397 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
396 sprintf(translated, "lib%s" DSO_ext, filename); 398 snprintf(translated, rsize, "lib%s" DSO_ext, filename);
397 else 399 else
398 sprintf(translated, "%s" DSO_ext, filename); 400 snprintf(translated, rsize, "%s" DSO_ext, filename);
399 } 401 }
400 else 402 else
401 sprintf(translated, "%s", filename); 403 snprintf(translated, rsize, "%s", filename);
402 return(translated); 404 return(translated);
403 } 405 }
404 406
405#ifdef __sgi 407#if defined(__sgi) && !defined(__OpenBSD__)
406/* 408/*
407This is a quote from IRIX manual for dladdr(3c): 409This is a quote from IRIX manual for dladdr(3c):
408 410
diff --git a/src/lib/libcrypto/dso/dso_vms.c b/src/lib/libcrypto/dso/dso_vms.c
new file mode 100644
index 0000000000..eee20d14f1
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_vms.c
@@ -0,0 +1,525 @@
1/* dso_vms.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61#include <errno.h>
62#include "cryptlib.h"
63#include <openssl/dso.h>
64#ifdef OPENSSL_SYS_VMS
65#pragma message disable DOLLARID
66#include <rms.h>
67#include <lib$routines.h>
68#include <stsdef.h>
69#include <descrip.h>
70#include <starlet.h>
71#include "vms_rms.h"
72#endif
73
74/* Some compiler options may mask the declaration of "_malloc32". */
75#if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
76# if __INITIAL_POINTER_SIZE == 64
77# pragma pointer_size save
78# pragma pointer_size 32
79 void * _malloc32 (__size_t);
80# pragma pointer_size restore
81# endif /* __INITIAL_POINTER_SIZE == 64 */
82#endif /* __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE */
83
84
85#ifndef OPENSSL_SYS_VMS
86DSO_METHOD *DSO_METHOD_vms(void)
87 {
88 return NULL;
89 }
90#else
91#pragma message disable DOLLARID
92
93static int vms_load(DSO *dso);
94static int vms_unload(DSO *dso);
95static void *vms_bind_var(DSO *dso, const char *symname);
96static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname);
97#if 0
98static int vms_unbind_var(DSO *dso, char *symname, void *symptr);
99static int vms_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
100static int vms_init(DSO *dso);
101static int vms_finish(DSO *dso);
102static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg);
103#endif
104static char *vms_name_converter(DSO *dso, const char *filename);
105static char *vms_merger(DSO *dso, const char *filespec1,
106 const char *filespec2);
107
108static DSO_METHOD dso_meth_vms = {
109 "OpenSSL 'VMS' shared library method",
110 vms_load,
111 NULL, /* unload */
112 vms_bind_var,
113 vms_bind_func,
114/* For now, "unbind" doesn't exist */
115#if 0
116 NULL, /* unbind_var */
117 NULL, /* unbind_func */
118#endif
119 NULL, /* ctrl */
120 vms_name_converter,
121 vms_merger,
122 NULL, /* init */
123 NULL /* finish */
124 };
125
126/* On VMS, the only "handle" is the file name. LIB$FIND_IMAGE_SYMBOL depends
127 * on the reference to the file name being the same for all calls regarding
128 * one shared image, so we'll just store it in an instance of the following
129 * structure and put a pointer to that instance in the meth_data stack.
130 */
131typedef struct dso_internal_st
132 {
133 /* This should contain the name only, no directory,
134 * no extension, nothing but a name. */
135 struct dsc$descriptor_s filename_dsc;
136 char filename[ NAMX_MAXRSS+ 1];
137 /* This contains whatever is not in filename, if needed.
138 * Normally not defined. */
139 struct dsc$descriptor_s imagename_dsc;
140 char imagename[ NAMX_MAXRSS+ 1];
141 } DSO_VMS_INTERNAL;
142
143DSO_METHOD *DSO_METHOD_vms(void)
144 {
145 return(&dso_meth_vms);
146 }
147
148static int vms_load(DSO *dso)
149 {
150 void *ptr = NULL;
151 /* See applicable comments in dso_dl.c */
152 char *filename = DSO_convert_filename(dso, NULL);
153
154/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */
155#if __INITIAL_POINTER_SIZE == 64
156# define DSO_MALLOC _malloc32
157# pragma pointer_size save
158# pragma pointer_size 32
159#else /* __INITIAL_POINTER_SIZE == 64 */
160# define DSO_MALLOC OPENSSL_malloc
161#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
162
163 DSO_VMS_INTERNAL *p = NULL;
164
165#if __INITIAL_POINTER_SIZE == 64
166# pragma pointer_size restore
167#endif /* __INITIAL_POINTER_SIZE == 64 */
168
169 const char *sp1, *sp2; /* Search result */
170
171 if(filename == NULL)
172 {
173 DSOerr(DSO_F_VMS_LOAD,DSO_R_NO_FILENAME);
174 goto err;
175 }
176
177 /* A file specification may look like this:
178 *
179 * node::dev:[dir-spec]name.type;ver
180 *
181 * or (for compatibility with TOPS-20):
182 *
183 * node::dev:<dir-spec>name.type;ver
184 *
185 * and the dir-spec uses '.' as separator. Also, a dir-spec
186 * may consist of several parts, with mixed use of [] and <>:
187 *
188 * [dir1.]<dir2>
189 *
190 * We need to split the file specification into the name and
191 * the rest (both before and after the name itself).
192 */
193 /* Start with trying to find the end of a dir-spec, and save the
194 position of the byte after in sp1 */
195 sp1 = strrchr(filename, ']');
196 sp2 = strrchr(filename, '>');
197 if (sp1 == NULL) sp1 = sp2;
198 if (sp2 != NULL && sp2 > sp1) sp1 = sp2;
199 if (sp1 == NULL) sp1 = strrchr(filename, ':');
200 if (sp1 == NULL)
201 sp1 = filename;
202 else
203 sp1++; /* The byte after the found character */
204 /* Now, let's see if there's a type, and save the position in sp2 */
205 sp2 = strchr(sp1, '.');
206 /* If we found it, that's where we'll cut. Otherwise, look for a
207 version number and save the position in sp2 */
208 if (sp2 == NULL) sp2 = strchr(sp1, ';');
209 /* If there was still nothing to find, set sp2 to point at the end of
210 the string */
211 if (sp2 == NULL) sp2 = sp1 + strlen(sp1);
212
213 /* Check that we won't get buffer overflows */
214 if (sp2 - sp1 > FILENAME_MAX
215 || (sp1 - filename) + strlen(sp2) > FILENAME_MAX)
216 {
217 DSOerr(DSO_F_VMS_LOAD,DSO_R_FILENAME_TOO_BIG);
218 goto err;
219 }
220
221 p = DSO_MALLOC(sizeof(DSO_VMS_INTERNAL));
222 if(p == NULL)
223 {
224 DSOerr(DSO_F_VMS_LOAD,ERR_R_MALLOC_FAILURE);
225 goto err;
226 }
227
228 strncpy(p->filename, sp1, sp2-sp1);
229 p->filename[sp2-sp1] = '\0';
230
231 strncpy(p->imagename, filename, sp1-filename);
232 p->imagename[sp1-filename] = '\0';
233 strcat(p->imagename, sp2);
234
235 p->filename_dsc.dsc$w_length = strlen(p->filename);
236 p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
237 p->filename_dsc.dsc$b_class = DSC$K_CLASS_S;
238 p->filename_dsc.dsc$a_pointer = p->filename;
239 p->imagename_dsc.dsc$w_length = strlen(p->imagename);
240 p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
241 p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S;
242 p->imagename_dsc.dsc$a_pointer = p->imagename;
243
244 if(!sk_void_push(dso->meth_data, (char *)p))
245 {
246 DSOerr(DSO_F_VMS_LOAD,DSO_R_STACK_ERROR);
247 goto err;
248 }
249
250 /* Success (for now, we lie. We actually do not know...) */
251 dso->loaded_filename = filename;
252 return(1);
253err:
254 /* Cleanup! */
255 if(p != NULL)
256 OPENSSL_free(p);
257 if(filename != NULL)
258 OPENSSL_free(filename);
259 return(0);
260 }
261
262/* Note that this doesn't actually unload the shared image, as there is no
263 * such thing in VMS. Next time it get loaded again, a new copy will
264 * actually be loaded.
265 */
266static int vms_unload(DSO *dso)
267 {
268 DSO_VMS_INTERNAL *p;
269 if(dso == NULL)
270 {
271 DSOerr(DSO_F_VMS_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
272 return(0);
273 }
274 if(sk_void_num(dso->meth_data) < 1)
275 return(1);
276 p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data);
277 if(p == NULL)
278 {
279 DSOerr(DSO_F_VMS_UNLOAD,DSO_R_NULL_HANDLE);
280 return(0);
281 }
282 /* Cleanup */
283 OPENSSL_free(p);
284 return(1);
285 }
286
287/* We must do this in a separate function because of the way the exception
288 handler works (it makes this function return */
289static int do_find_symbol(DSO_VMS_INTERNAL *ptr,
290 struct dsc$descriptor_s *symname_dsc, void **sym,
291 unsigned long flags)
292 {
293 /* Make sure that signals are caught and returned instead of
294 aborting the program. The exception handler gets unestablished
295 automatically on return from this function. */
296 lib$establish(lib$sig_to_ret);
297
298 if(ptr->imagename_dsc.dsc$w_length)
299 return lib$find_image_symbol(&ptr->filename_dsc,
300 symname_dsc, sym,
301 &ptr->imagename_dsc, flags);
302 else
303 return lib$find_image_symbol(&ptr->filename_dsc,
304 symname_dsc, sym,
305 0, flags);
306 }
307
308void vms_bind_sym(DSO *dso, const char *symname, void **sym)
309 {
310 DSO_VMS_INTERNAL *ptr;
311 int status;
312#if 0
313 int flags = (1<<4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't
314 defined in VMS older than 7.0 or so */
315#else
316 int flags = 0;
317#endif
318 struct dsc$descriptor_s symname_dsc;
319
320/* Arrange 32-bit pointer to (copied) string storage, if needed. */
321#if __INITIAL_POINTER_SIZE == 64
322# define SYMNAME symname_32p
323# pragma pointer_size save
324# pragma pointer_size 32
325 char *symname_32p;
326# pragma pointer_size restore
327 char symname_32[ NAMX_MAXRSS+ 1];
328#else /* __INITIAL_POINTER_SIZE == 64 */
329# define SYMNAME ((char *) symname)
330#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
331
332 *sym = NULL;
333
334 if((dso == NULL) || (symname == NULL))
335 {
336 DSOerr(DSO_F_VMS_BIND_SYM,ERR_R_PASSED_NULL_PARAMETER);
337 return;
338 }
339
340#if __INITIAL_POINTER_SIZE == 64
341 /* Copy the symbol name to storage with a 32-bit pointer. */
342 symname_32p = symname_32;
343 strcpy( symname_32p, symname);
344#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
345
346 symname_dsc.dsc$w_length = strlen(SYMNAME);
347 symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
348 symname_dsc.dsc$b_class = DSC$K_CLASS_S;
349 symname_dsc.dsc$a_pointer = SYMNAME;
350
351 if(sk_void_num(dso->meth_data) < 1)
352 {
353 DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_STACK_ERROR);
354 return;
355 }
356 ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data,
357 sk_void_num(dso->meth_data) - 1);
358 if(ptr == NULL)
359 {
360 DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_NULL_HANDLE);
361 return;
362 }
363
364 if(dso->flags & DSO_FLAG_UPCASE_SYMBOL) flags = 0;
365
366 status = do_find_symbol(ptr, &symname_dsc, sym, flags);
367
368 if(!$VMS_STATUS_SUCCESS(status))
369 {
370 unsigned short length;
371 char errstring[257];
372 struct dsc$descriptor_s errstring_dsc;
373
374 errstring_dsc.dsc$w_length = sizeof(errstring);
375 errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
376 errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
377 errstring_dsc.dsc$a_pointer = errstring;
378
379 *sym = NULL;
380
381 status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
382
383 if (!$VMS_STATUS_SUCCESS(status))
384 lib$signal(status); /* This is really bad. Abort! */
385 else
386 {
387 errstring[length] = '\0';
388
389 DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_SYM_FAILURE);
390 if (ptr->imagename_dsc.dsc$w_length)
391 ERR_add_error_data(9,
392 "Symbol ", symname,
393 " in ", ptr->filename,
394 " (", ptr->imagename, ")",
395 ": ", errstring);
396 else
397 ERR_add_error_data(6,
398 "Symbol ", symname,
399 " in ", ptr->filename,
400 ": ", errstring);
401 }
402 return;
403 }
404 return;
405 }
406
407static void *vms_bind_var(DSO *dso, const char *symname)
408 {
409 void *sym = 0;
410 vms_bind_sym(dso, symname, &sym);
411 return sym;
412 }
413
414static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname)
415 {
416 DSO_FUNC_TYPE sym = 0;
417 vms_bind_sym(dso, symname, (void **)&sym);
418 return sym;
419 }
420
421
422static char *vms_merger(DSO *dso, const char *filespec1, const char *filespec2)
423 {
424 int status;
425 int filespec1len, filespec2len;
426 struct FAB fab;
427 struct NAMX_STRUCT nam;
428 char esa[ NAMX_MAXRSS+ 1];
429 char *merged;
430
431/* Arrange 32-bit pointer to (copied) string storage, if needed. */
432#if __INITIAL_POINTER_SIZE == 64
433# define FILESPEC1 filespec1_32p;
434# define FILESPEC2 filespec2_32p;
435# pragma pointer_size save
436# pragma pointer_size 32
437 char *filespec1_32p;
438 char *filespec2_32p;
439# pragma pointer_size restore
440 char filespec1_32[ NAMX_MAXRSS+ 1];
441 char filespec2_32[ NAMX_MAXRSS+ 1];
442#else /* __INITIAL_POINTER_SIZE == 64 */
443# define FILESPEC1 ((char *) filespec1)
444# define FILESPEC2 ((char *) filespec2)
445#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
446
447 if (!filespec1) filespec1 = "";
448 if (!filespec2) filespec2 = "";
449 filespec1len = strlen(filespec1);
450 filespec2len = strlen(filespec2);
451
452#if __INITIAL_POINTER_SIZE == 64
453 /* Copy the file names to storage with a 32-bit pointer. */
454 filespec1_32p = filespec1_32;
455 filespec2_32p = filespec2_32;
456 strcpy( filespec1_32p, filespec1);
457 strcpy( filespec2_32p, filespec2);
458#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
459
460 fab = cc$rms_fab;
461 nam = CC_RMS_NAMX;
462
463 FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = FILESPEC1;
464 FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = filespec1len;
465 FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNA = FILESPEC2;
466 FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNS = filespec2len;
467 NAMX_DNA_FNA_SET( fab)
468
469 nam.NAMX_ESA = esa;
470 nam.NAMX_ESS = NAMX_MAXRSS;
471 nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD;
472 SET_NAMX_NO_SHORT_UPCASE( nam);
473
474 fab.FAB_NAMX = &nam;
475
476 status = sys$parse(&fab, 0, 0);
477
478 if(!$VMS_STATUS_SUCCESS(status))
479 {
480 unsigned short length;
481 char errstring[257];
482 struct dsc$descriptor_s errstring_dsc;
483
484 errstring_dsc.dsc$w_length = sizeof(errstring);
485 errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
486 errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
487 errstring_dsc.dsc$a_pointer = errstring;
488
489 status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
490
491 if (!$VMS_STATUS_SUCCESS(status))
492 lib$signal(status); /* This is really bad. Abort! */
493 else
494 {
495 errstring[length] = '\0';
496
497 DSOerr(DSO_F_VMS_MERGER,DSO_R_FAILURE);
498 ERR_add_error_data(7,
499 "filespec \"", filespec1, "\", ",
500 "defaults \"", filespec2, "\": ",
501 errstring);
502 }
503 return(NULL);
504 }
505
506 merged = OPENSSL_malloc( nam.NAMX_ESL+ 1);
507 if(!merged)
508 goto malloc_err;
509 strncpy( merged, nam.NAMX_ESA, nam.NAMX_ESL);
510 merged[ nam.NAMX_ESL] = '\0';
511 return(merged);
512 malloc_err:
513 DSOerr(DSO_F_VMS_MERGER,
514 ERR_R_MALLOC_FAILURE);
515 }
516
517static char *vms_name_converter(DSO *dso, const char *filename)
518 {
519 int len = strlen(filename);
520 char *not_translated = OPENSSL_malloc(len+1);
521 strcpy(not_translated,filename);
522 return(not_translated);
523 }
524
525#endif /* OPENSSL_SYS_VMS */
diff --git a/src/lib/libcrypto/dso/dso_win32.c b/src/lib/libcrypto/dso/dso_win32.c
new file mode 100644
index 0000000000..6fb6c54181
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_win32.c
@@ -0,0 +1,844 @@
1/* dso_win32.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61#include "cryptlib.h"
62#include <openssl/dso.h>
63
64#if !defined(DSO_WIN32)
65DSO_METHOD *DSO_METHOD_win32(void)
66 {
67 return NULL;
68 }
69#else
70
71#ifdef _WIN32_WCE
72# if _WIN32_WCE < 300
73static FARPROC GetProcAddressA(HMODULE hModule,LPCSTR lpProcName)
74 {
75 WCHAR lpProcNameW[64];
76 int i;
77
78 for (i=0;lpProcName[i] && i<64;i++)
79 lpProcNameW[i] = (WCHAR)lpProcName[i];
80 if (i==64) return NULL;
81 lpProcNameW[i] = 0;
82
83 return GetProcAddressW(hModule,lpProcNameW);
84 }
85# endif
86# undef GetProcAddress
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)
100 {
101 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
102 return NULL;
103 }
104
105#if defined(_WIN32_WCE) && _WIN32_WCE>=101
106 if (!MultiByteToWideChar(CP_ACP,0,lpLibFileName,len_0,fnamw,len_0))
107#endif
108 for (i=0;i<len_0;i++) fnamw[i]=(WCHAR)lpLibFileName[i];
109
110 return LoadLibraryW(fnamw);
111 }
112#endif
113
114/* Part of the hack in "win32_load" ... */
115#define DSO_MAX_TRANSLATED_SIZE 256
116
117static int win32_load(DSO *dso);
118static int win32_unload(DSO *dso);
119static void *win32_bind_var(DSO *dso, const char *symname);
120static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
121#if 0
122static int win32_unbind_var(DSO *dso, char *symname, void *symptr);
123static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
124static int win32_init(DSO *dso);
125static int win32_finish(DSO *dso);
126static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
127#endif
128static char *win32_name_converter(DSO *dso, const char *filename);
129static char *win32_merger(DSO *dso, const char *filespec1,
130 const char *filespec2);
131static int win32_pathbyaddr(void *addr,char *path,int sz);
132static void *win32_globallookup(const char *name);
133
134static const char *openssl_strnchr(const char *string, int c, size_t len);
135
136static DSO_METHOD dso_meth_win32 = {
137 "OpenSSL 'win32' shared library method",
138 win32_load,
139 win32_unload,
140 win32_bind_var,
141 win32_bind_func,
142/* For now, "unbind" doesn't exist */
143#if 0
144 NULL, /* unbind_var */
145 NULL, /* unbind_func */
146#endif
147 NULL, /* ctrl */
148 win32_name_converter,
149 win32_merger,
150 NULL, /* init */
151 NULL, /* finish */
152 win32_pathbyaddr,
153 win32_globallookup
154 };
155
156DSO_METHOD *DSO_METHOD_win32(void)
157 {
158 return(&dso_meth_win32);
159 }
160
161/* For this DSO_METHOD, our meth_data STACK will contain;
162 * (i) a pointer to the handle (HINSTANCE) returned from
163 * LoadLibrary(), and copied.
164 */
165
166static int win32_load(DSO *dso)
167 {
168 HINSTANCE h = NULL, *p = NULL;
169 /* See applicable comments from dso_dl.c */
170 char *filename = DSO_convert_filename(dso, NULL);
171
172 if(filename == NULL)
173 {
174 DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME);
175 goto err;
176 }
177 h = LoadLibraryA(filename);
178 if(h == NULL)
179 {
180 DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
181 ERR_add_error_data(3, "filename(", filename, ")");
182 goto err;
183 }
184 p = (HINSTANCE *)OPENSSL_malloc(sizeof(HINSTANCE));
185 if(p == NULL)
186 {
187 DSOerr(DSO_F_WIN32_LOAD,ERR_R_MALLOC_FAILURE);
188 goto err;
189 }
190 *p = h;
191 if(!sk_void_push(dso->meth_data, p))
192 {
193 DSOerr(DSO_F_WIN32_LOAD,DSO_R_STACK_ERROR);
194 goto err;
195 }
196 /* Success */
197 dso->loaded_filename = filename;
198 return(1);
199err:
200 /* Cleanup !*/
201 if(filename != NULL)
202 OPENSSL_free(filename);
203 if(p != NULL)
204 OPENSSL_free(p);
205 if(h != NULL)
206 FreeLibrary(h);
207 return(0);
208 }
209
210static int win32_unload(DSO *dso)
211 {
212 HINSTANCE *p;
213 if(dso == NULL)
214 {
215 DSOerr(DSO_F_WIN32_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
216 return(0);
217 }
218 if(sk_void_num(dso->meth_data) < 1)
219 return(1);
220 p = sk_void_pop(dso->meth_data);
221 if(p == NULL)
222 {
223 DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_NULL_HANDLE);
224 return(0);
225 }
226 if(!FreeLibrary(*p))
227 {
228 DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_UNLOAD_FAILED);
229 /* We should push the value back onto the stack in
230 * case of a retry. */
231 sk_void_push(dso->meth_data, p);
232 return(0);
233 }
234 /* Cleanup */
235 OPENSSL_free(p);
236 return(1);
237 }
238
239/* Using GetProcAddress for variables? TODO: Check this out in
240 * the Win32 API docs, there's probably a variant for variables. */
241static void *win32_bind_var(DSO *dso, const char *symname)
242 {
243 HINSTANCE *ptr;
244 void *sym;
245
246 if((dso == NULL) || (symname == NULL))
247 {
248 DSOerr(DSO_F_WIN32_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
249 return(NULL);
250 }
251 if(sk_void_num(dso->meth_data) < 1)
252 {
253 DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_STACK_ERROR);
254 return(NULL);
255 }
256 ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
257 if(ptr == NULL)
258 {
259 DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_NULL_HANDLE);
260 return(NULL);
261 }
262 sym = GetProcAddress(*ptr, symname);
263 if(sym == NULL)
264 {
265 DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_SYM_FAILURE);
266 ERR_add_error_data(3, "symname(", symname, ")");
267 return(NULL);
268 }
269 return(sym);
270 }
271
272static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
273 {
274 HINSTANCE *ptr;
275 void *sym;
276
277 if((dso == NULL) || (symname == NULL))
278 {
279 DSOerr(DSO_F_WIN32_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
280 return(NULL);
281 }
282 if(sk_void_num(dso->meth_data) < 1)
283 {
284 DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_STACK_ERROR);
285 return(NULL);
286 }
287 ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
288 if(ptr == NULL)
289 {
290 DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_NULL_HANDLE);
291 return(NULL);
292 }
293 sym = GetProcAddress(*ptr, symname);
294 if(sym == NULL)
295 {
296 DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_SYM_FAILURE);
297 ERR_add_error_data(3, "symname(", symname, ")");
298 return(NULL);
299 }
300 return((DSO_FUNC_TYPE)sym);
301 }
302
303struct file_st
304 {
305 const char *node; int nodelen;
306 const char *device; int devicelen;
307 const char *predir; int predirlen;
308 const char *dir; int dirlen;
309 const char *file; int filelen;
310 };
311
312static struct file_st *win32_splitter(DSO *dso, const char *filename,
313 int assume_last_is_dir)
314 {
315 struct file_st *result = NULL;
316 enum { IN_NODE, IN_DEVICE, IN_FILE } position;
317 const char *start = filename;
318 char last;
319
320 if (!filename)
321 {
322 DSOerr(DSO_F_WIN32_SPLITTER,DSO_R_NO_FILENAME);
323 /*goto err;*/
324 return(NULL);
325 }
326
327 result = OPENSSL_malloc(sizeof(struct file_st));
328 if(result == NULL)
329 {
330 DSOerr(DSO_F_WIN32_SPLITTER,
331 ERR_R_MALLOC_FAILURE);
332 return(NULL);
333 }
334
335 memset(result, 0, sizeof(struct file_st));
336 position = IN_DEVICE;
337
338 if((filename[0] == '\\' && filename[1] == '\\')
339 || (filename[0] == '/' && filename[1] == '/'))
340 {
341 position = IN_NODE;
342 filename += 2;
343 start = filename;
344 result->node = start;
345 }
346
347 do
348 {
349 last = filename[0];
350 switch(last)
351 {
352 case ':':
353 if(position != IN_DEVICE)
354 {
355 DSOerr(DSO_F_WIN32_SPLITTER,
356 DSO_R_INCORRECT_FILE_SYNTAX);
357 /*goto err;*/
358 OPENSSL_free(result);
359 return(NULL);
360 }
361 result->device = start;
362 result->devicelen = (int)(filename - start);
363 position = IN_FILE;
364 start = ++filename;
365 result->dir = start;
366 break;
367 case '\\':
368 case '/':
369 if(position == IN_NODE)
370 {
371 result->nodelen = (int)(filename - start);
372 position = IN_FILE;
373 start = ++filename;
374 result->dir = start;
375 }
376 else if(position == IN_DEVICE)
377 {
378 position = IN_FILE;
379 filename++;
380 result->dir = start;
381 result->dirlen = (int)(filename - start);
382 start = filename;
383 }
384 else
385 {
386 filename++;
387 result->dirlen += (int)(filename - start);
388 start = filename;
389 }
390 break;
391 case '\0':
392 if(position == IN_NODE)
393 {
394 result->nodelen = (int)(filename - start);
395 }
396 else
397 {
398 if(filename - start > 0)
399 {
400 if (assume_last_is_dir)
401 {
402 if (position == IN_DEVICE)
403 {
404 result->dir = start;
405 result->dirlen = 0;
406 }
407 result->dirlen +=
408 (int)(filename - start);
409 }
410 else
411 {
412 result->file = start;
413 result->filelen =
414 (int)(filename - start);
415 }
416 }
417 }
418 break;
419 default:
420 filename++;
421 break;
422 }
423 }
424 while(last);
425
426 if(!result->nodelen) result->node = NULL;
427 if(!result->devicelen) result->device = NULL;
428 if(!result->dirlen) result->dir = NULL;
429 if(!result->filelen) result->file = NULL;
430
431 return(result);
432 }
433
434static char *win32_joiner(DSO *dso, const struct file_st *file_split)
435 {
436 int len = 0, offset = 0;
437 char *result = NULL;
438 const char *start;
439
440 if(!file_split)
441 {
442 DSOerr(DSO_F_WIN32_JOINER,
443 ERR_R_PASSED_NULL_PARAMETER);
444 return(NULL);
445 }
446 if(file_split->node)
447 {
448 len += 2 + file_split->nodelen; /* 2 for starting \\ */
449 if(file_split->predir || file_split->dir || file_split->file)
450 len++; /* 1 for ending \ */
451 }
452 else if(file_split->device)
453 {
454 len += file_split->devicelen + 1; /* 1 for ending : */
455 }
456 len += file_split->predirlen;
457 if(file_split->predir && (file_split->dir || file_split->file))
458 {
459 len++; /* 1 for ending \ */
460 }
461 len += file_split->dirlen;
462 if(file_split->dir && file_split->file)
463 {
464 len++; /* 1 for ending \ */
465 }
466 len += file_split->filelen;
467
468 if(!len)
469 {
470 DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE);
471 return(NULL);
472 }
473
474 result = OPENSSL_malloc(len + 1);
475 if (!result)
476 {
477 DSOerr(DSO_F_WIN32_JOINER,
478 ERR_R_MALLOC_FAILURE);
479 return(NULL);
480 }
481
482 if(file_split->node)
483 {
484 strcpy(&result[offset], "\\\\"); offset += 2;
485 strncpy(&result[offset], file_split->node,
486 file_split->nodelen); offset += file_split->nodelen;
487 if(file_split->predir || file_split->dir || file_split->file)
488 {
489 result[offset] = '\\'; offset++;
490 }
491 }
492 else if(file_split->device)
493 {
494 strncpy(&result[offset], file_split->device,
495 file_split->devicelen); offset += file_split->devicelen;
496 result[offset] = ':'; offset++;
497 }
498 start = file_split->predir;
499 while(file_split->predirlen > (start - file_split->predir))
500 {
501 const char *end = openssl_strnchr(start, '/',
502 file_split->predirlen - (start - file_split->predir));
503 if(!end)
504 end = start
505 + file_split->predirlen
506 - (start - file_split->predir);
507 strncpy(&result[offset], start,
508 end - start); offset += (int)(end - start);
509 result[offset] = '\\'; offset++;
510 start = end + 1;
511 }
512#if 0 /* Not needed, since the directory converter above already appeneded
513 a backslash */
514 if(file_split->predir && (file_split->dir || file_split->file))
515 {
516 result[offset] = '\\'; offset++;
517 }
518#endif
519 start = file_split->dir;
520 while(file_split->dirlen > (start - file_split->dir))
521 {
522 const char *end = openssl_strnchr(start, '/',
523 file_split->dirlen - (start - file_split->dir));
524 if(!end)
525 end = start
526 + file_split->dirlen
527 - (start - file_split->dir);
528 strncpy(&result[offset], start,
529 end - start); offset += (int)(end - start);
530 result[offset] = '\\'; offset++;
531 start = end + 1;
532 }
533#if 0 /* Not needed, since the directory converter above already appeneded
534 a backslash */
535 if(file_split->dir && file_split->file)
536 {
537 result[offset] = '\\'; offset++;
538 }
539#endif
540 strncpy(&result[offset], file_split->file,
541 file_split->filelen); offset += file_split->filelen;
542 result[offset] = '\0';
543 return(result);
544 }
545
546static char *win32_merger(DSO *dso, const char *filespec1, const char *filespec2)
547 {
548 char *merged = NULL;
549 struct file_st *filespec1_split = NULL;
550 struct file_st *filespec2_split = NULL;
551
552 if(!filespec1 && !filespec2)
553 {
554 DSOerr(DSO_F_WIN32_MERGER,
555 ERR_R_PASSED_NULL_PARAMETER);
556 return(NULL);
557 }
558 if (!filespec2)
559 {
560 merged = OPENSSL_malloc(strlen(filespec1) + 1);
561 if(!merged)
562 {
563 DSOerr(DSO_F_WIN32_MERGER,
564 ERR_R_MALLOC_FAILURE);
565 return(NULL);
566 }
567 strcpy(merged, filespec1);
568 }
569 else if (!filespec1)
570 {
571 merged = OPENSSL_malloc(strlen(filespec2) + 1);
572 if(!merged)
573 {
574 DSOerr(DSO_F_WIN32_MERGER,
575 ERR_R_MALLOC_FAILURE);
576 return(NULL);
577 }
578 strcpy(merged, filespec2);
579 }
580 else
581 {
582 filespec1_split = win32_splitter(dso, filespec1, 0);
583 if (!filespec1_split)
584 {
585 DSOerr(DSO_F_WIN32_MERGER,
586 ERR_R_MALLOC_FAILURE);
587 return(NULL);
588 }
589 filespec2_split = win32_splitter(dso, filespec2, 1);
590 if (!filespec2_split)
591 {
592 DSOerr(DSO_F_WIN32_MERGER,
593 ERR_R_MALLOC_FAILURE);
594 OPENSSL_free(filespec1_split);
595 return(NULL);
596 }
597
598 /* Fill in into filespec1_split */
599 if (!filespec1_split->node && !filespec1_split->device)
600 {
601 filespec1_split->node = filespec2_split->node;
602 filespec1_split->nodelen = filespec2_split->nodelen;
603 filespec1_split->device = filespec2_split->device;
604 filespec1_split->devicelen = filespec2_split->devicelen;
605 }
606 if (!filespec1_split->dir)
607 {
608 filespec1_split->dir = filespec2_split->dir;
609 filespec1_split->dirlen = filespec2_split->dirlen;
610 }
611 else if (filespec1_split->dir[0] != '\\'
612 && filespec1_split->dir[0] != '/')
613 {
614 filespec1_split->predir = filespec2_split->dir;
615 filespec1_split->predirlen = filespec2_split->dirlen;
616 }
617 if (!filespec1_split->file)
618 {
619 filespec1_split->file = filespec2_split->file;
620 filespec1_split->filelen = filespec2_split->filelen;
621 }
622
623 merged = win32_joiner(dso, filespec1_split);
624 }
625 OPENSSL_free(filespec1_split);
626 OPENSSL_free(filespec2_split);
627 return(merged);
628 }
629
630static char *win32_name_converter(DSO *dso, const char *filename)
631 {
632 char *translated;
633 int len, transform;
634
635 len = strlen(filename);
636 transform = ((strstr(filename, "/") == NULL) &&
637 (strstr(filename, "\\") == NULL) &&
638 (strstr(filename, ":") == NULL));
639 if(transform)
640 /* We will convert this to "%s.dll" */
641 translated = OPENSSL_malloc(len + 5);
642 else
643 /* We will simply duplicate filename */
644 translated = OPENSSL_malloc(len + 1);
645 if(translated == NULL)
646 {
647 DSOerr(DSO_F_WIN32_NAME_CONVERTER,
648 DSO_R_NAME_TRANSLATION_FAILED);
649 return(NULL);
650 }
651 if(transform)
652 sprintf(translated, "%s.dll", filename);
653 else
654 sprintf(translated, "%s", filename);
655 return(translated);
656 }
657
658static const char *openssl_strnchr(const char *string, int c, size_t len)
659 {
660 size_t i;
661 const char *p;
662 for (i = 0, p = string; i < len && *p; i++, p++)
663 {
664 if (*p == c)
665 return p;
666 }
667 return NULL;
668 }
669
670#include <tlhelp32.h>
671#ifdef _WIN32_WCE
672# define DLLNAME "TOOLHELP.DLL"
673#else
674# ifdef MODULEENTRY32
675# undef MODULEENTRY32 /* unmask the ASCII version! */
676# endif
677# define DLLNAME "KERNEL32.DLL"
678#endif
679
680typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
681typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
682typedef BOOL (WINAPI *MODULE32)(HANDLE, MODULEENTRY32 *);
683
684static int win32_pathbyaddr(void *addr,char *path,int sz)
685 {
686 HMODULE dll;
687 HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
688 MODULEENTRY32 me32;
689 CREATETOOLHELP32SNAPSHOT create_snap;
690 CLOSETOOLHELP32SNAPSHOT close_snap;
691 MODULE32 module_first, module_next;
692 int len;
693
694 if (addr == NULL)
695 {
696 union { int(*f)(void*,char*,int); void *p; } t =
697 { win32_pathbyaddr };
698 addr = t.p;
699 }
700
701 dll = LoadLibrary(TEXT(DLLNAME));
702 if (dll == NULL)
703 {
704 DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
705 return -1;
706 }
707
708 create_snap = (CREATETOOLHELP32SNAPSHOT)
709 GetProcAddress(dll,"CreateToolhelp32Snapshot");
710 if (create_snap == NULL)
711 {
712 FreeLibrary(dll);
713 DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
714 return -1;
715 }
716 /* We take the rest for granted... */
717#ifdef _WIN32_WCE
718 close_snap = (CLOSETOOLHELP32SNAPSHOT)
719 GetProcAddress(dll,"CloseToolhelp32Snapshot");
720#else
721 close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
722#endif
723 module_first = (MODULE32)GetProcAddress(dll,"Module32First");
724 module_next = (MODULE32)GetProcAddress(dll,"Module32Next");
725
726 hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0);
727 if( hModuleSnap == INVALID_HANDLE_VALUE )
728 {
729 FreeLibrary(dll);
730 DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
731 return -1;
732 }
733
734 me32.dwSize = sizeof(me32);
735
736 if(!(*module_first)(hModuleSnap,&me32))
737 {
738 (*close_snap)(hModuleSnap);
739 FreeLibrary(dll);
740 DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_FAILURE);
741 return -1;
742 }
743
744 do {
745 if ((BYTE *)addr >= me32.modBaseAddr &&
746 (BYTE *)addr < me32.modBaseAddr+me32.modBaseSize)
747 {
748 (*close_snap)(hModuleSnap);
749 FreeLibrary(dll);
750#ifdef _WIN32_WCE
751# if _WIN32_WCE >= 101
752 return WideCharToMultiByte(CP_ACP,0,me32.szExePath,-1,
753 path,sz,NULL,NULL);
754# else
755 len = (int)wcslen(me32.szExePath);
756 if (sz <= 0) return len+1;
757 if (len >= sz) len=sz-1;
758 for(i=0;i<len;i++)
759 path[i] = (char)me32.szExePath[i];
760 path[len++] = 0;
761 return len;
762# endif
763#else
764 len = (int)strlen(me32.szExePath);
765 if (sz <= 0) return len+1;
766 if (len >= sz) len=sz-1;
767 memcpy(path,me32.szExePath,len);
768 path[len++] = 0;
769 return len;
770#endif
771 }
772 } while((*module_next)(hModuleSnap, &me32));
773
774 (*close_snap)(hModuleSnap);
775 FreeLibrary(dll);
776 return 0;
777 }
778
779static void *win32_globallookup(const char *name)
780 {
781 HMODULE dll;
782 HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
783 MODULEENTRY32 me32;
784 CREATETOOLHELP32SNAPSHOT create_snap;
785 CLOSETOOLHELP32SNAPSHOT close_snap;
786 MODULE32 module_first, module_next;
787 FARPROC ret=NULL;
788
789 dll = LoadLibrary(TEXT(DLLNAME));
790 if (dll == NULL)
791 {
792 DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
793 return NULL;
794 }
795
796 create_snap = (CREATETOOLHELP32SNAPSHOT)
797 GetProcAddress(dll,"CreateToolhelp32Snapshot");
798 if (create_snap == NULL)
799 {
800 FreeLibrary(dll);
801 DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
802 return NULL;
803 }
804 /* We take the rest for granted... */
805#ifdef _WIN32_WCE
806 close_snap = (CLOSETOOLHELP32SNAPSHOT)
807 GetProcAddress(dll,"CloseToolhelp32Snapshot");
808#else
809 close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
810#endif
811 module_first = (MODULE32)GetProcAddress(dll,"Module32First");
812 module_next = (MODULE32)GetProcAddress(dll,"Module32Next");
813
814 hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0);
815 if( hModuleSnap == INVALID_HANDLE_VALUE )
816 {
817 FreeLibrary(dll);
818 DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
819 return NULL;
820 }
821
822 me32.dwSize = sizeof(me32);
823
824 if (!(*module_first)(hModuleSnap,&me32))
825 {
826 (*close_snap)(hModuleSnap);
827 FreeLibrary(dll);
828 return NULL;
829 }
830
831 do {
832 if ((ret = GetProcAddress(me32.hModule,name)))
833 {
834 (*close_snap)(hModuleSnap);
835 FreeLibrary(dll);
836 return ret;
837 }
838 } while((*module_next)(hModuleSnap,&me32));
839
840 (*close_snap)(hModuleSnap);
841 FreeLibrary(dll);
842 return NULL;
843 }
844#endif /* DSO_WIN32 */