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/Makefile142
-rw-r--r--src/lib/libcrypto/dso/README22
-rw-r--r--src/lib/libcrypto/dso/dso.h368
-rw-r--r--src/lib/libcrypto/dso/dso_dl.c353
-rw-r--r--src/lib/libcrypto/dso/dso_dlfcn.c372
-rw-r--r--src/lib/libcrypto/dso/dso_err.c147
-rw-r--r--src/lib/libcrypto/dso/dso_lib.c466
-rw-r--r--src/lib/libcrypto/dso/dso_null.c88
-rw-r--r--src/lib/libcrypto/dso/dso_openssl.c81
-rw-r--r--src/lib/libcrypto/dso/dso_vms.c504
-rw-r--r--src/lib/libcrypto/dso/dso_win32.c660
11 files changed, 3203 insertions, 0 deletions
diff --git a/src/lib/libcrypto/dso/Makefile b/src/lib/libcrypto/dso/Makefile
new file mode 100644
index 0000000000..07f5d8d159
--- /dev/null
+++ b/src/lib/libcrypto/dso/Makefile
@@ -0,0 +1,142 @@
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
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
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_dl.o: ../../e_os.h ../../include/openssl/bio.h
80dso_dl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
81dso_dl.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
82dso_dl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
83dso_dl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
84dso_dl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
85dso_dl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
86dso_dl.o: ../cryptlib.h dso_dl.c
87dso_dlfcn.o: ../../e_os.h ../../include/openssl/bio.h
88dso_dlfcn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
89dso_dlfcn.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
90dso_dlfcn.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
91dso_dlfcn.o: ../../include/openssl/opensslconf.h
92dso_dlfcn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
93dso_dlfcn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
94dso_dlfcn.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_dlfcn.c
95dso_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
96dso_err.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
97dso_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
98dso_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
99dso_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
100dso_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
101dso_err.o: dso_err.c
102dso_lib.o: ../../e_os.h ../../include/openssl/bio.h
103dso_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
104dso_lib.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
105dso_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
106dso_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
107dso_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
108dso_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
109dso_lib.o: ../cryptlib.h dso_lib.c
110dso_null.o: ../../e_os.h ../../include/openssl/bio.h
111dso_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
112dso_null.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
113dso_null.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
114dso_null.o: ../../include/openssl/opensslconf.h
115dso_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
116dso_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
117dso_null.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_null.c
118dso_openssl.o: ../../e_os.h ../../include/openssl/bio.h
119dso_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
120dso_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
121dso_openssl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
122dso_openssl.o: ../../include/openssl/opensslconf.h
123dso_openssl.o: ../../include/openssl/opensslv.h
124dso_openssl.o: ../../include/openssl/ossl_typ.h
125dso_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
126dso_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_openssl.c
127dso_vms.o: ../../e_os.h ../../include/openssl/bio.h
128dso_vms.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
129dso_vms.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
130dso_vms.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
131dso_vms.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
132dso_vms.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
133dso_vms.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
134dso_vms.o: ../cryptlib.h dso_vms.c
135dso_win32.o: ../../e_os.h ../../include/openssl/bio.h
136dso_win32.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
137dso_win32.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
138dso_win32.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
139dso_win32.o: ../../include/openssl/opensslconf.h
140dso_win32.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
141dso_win32.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
142dso_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.h b/src/lib/libcrypto/dso/dso.h
new file mode 100644
index 0000000000..3e51913a72
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso.h
@@ -0,0 +1,368 @@
1/* dso.h -*- 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#ifndef HEADER_DSO_H
60#define HEADER_DSO_H
61
62#include <openssl/crypto.h>
63
64#ifdef __cplusplus
65extern "C" {
66#endif
67
68/* These values are used as commands to DSO_ctrl() */
69#define DSO_CTRL_GET_FLAGS 1
70#define DSO_CTRL_SET_FLAGS 2
71#define DSO_CTRL_OR_FLAGS 3
72
73/* By default, DSO_load() will translate the provided filename into a form
74 * typical for the platform (more specifically the DSO_METHOD) using the
75 * dso_name_converter function of the method. Eg. win32 will transform "blah"
76 * into "blah.dll", and dlfcn will transform it into "libblah.so". The
77 * behaviour can be overriden by setting the name_converter callback in the DSO
78 * object (using DSO_set_name_converter()). This callback could even utilise
79 * the DSO_METHOD's converter too if it only wants to override behaviour for
80 * one or two possible DSO methods. However, the following flag can be set in a
81 * DSO to prevent *any* native name-translation at all - eg. if the caller has
82 * prompted the user for a path to a driver library so the filename should be
83 * interpreted as-is. */
84#define DSO_FLAG_NO_NAME_TRANSLATION 0x01
85/* An extra flag to give if only the extension should be added as
86 * translation. This is obviously only of importance on Unix and
87 * other operating systems where the translation also may prefix
88 * the name with something, like 'lib', and ignored everywhere else.
89 * This flag is also ignored if DSO_FLAG_NO_NAME_TRANSLATION is used
90 * at the same time. */
91#define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY 0x02
92
93/* The following flag controls the translation of symbol names to upper
94 * case. This is currently only being implemented for OpenVMS.
95 */
96#define DSO_FLAG_UPCASE_SYMBOL 0x10
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
105
106typedef void (*DSO_FUNC_TYPE)(void);
107
108typedef struct dso_st DSO;
109
110/* The function prototype used for method functions (or caller-provided
111 * callbacks) that transform filenames. They are passed a DSO structure pointer
112 * (or NULL if they are to be used independantly of a DSO object) and a
113 * filename to transform. They should either return NULL (if there is an error
114 * condition) or a newly allocated string containing the transformed form that
115 * the caller will need to free with OPENSSL_free() when done. */
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 *);
133
134typedef struct dso_meth_st
135 {
136 const char *name;
137 /* Loads a shared library, NB: new DSO_METHODs must ensure that a
138 * successful load populates the loaded_filename field, and likewise a
139 * successful unload OPENSSL_frees and NULLs it out. */
140 int (*dso_load)(DSO *dso);
141 /* Unloads a shared library */
142 int (*dso_unload)(DSO *dso);
143 /* Binds a variable */
144 void *(*dso_bind_var)(DSO *dso, const char *symname);
145 /* Binds a function - assumes a return type of DSO_FUNC_TYPE.
146 * This should be cast to the real function prototype by the
147 * caller. Platforms that don't have compatible representations
148 * for different prototypes (this is possible within ANSI C)
149 * are highly unlikely to have shared libraries at all, let
150 * alone a DSO_METHOD implemented for them. */
151 DSO_FUNC_TYPE (*dso_bind_func)(DSO *dso, const char *symname);
152
153/* I don't think this would actually be used in any circumstances. */
154#if 0
155 /* Unbinds a variable */
156 int (*dso_unbind_var)(DSO *dso, char *symname, void *symptr);
157 /* Unbinds a function */
158 int (*dso_unbind_func)(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
159#endif
160 /* The generic (yuck) "ctrl()" function. NB: Negative return
161 * values (rather than zero) indicate errors. */
162 long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg);
163 /* The default DSO_METHOD-specific function for converting filenames to
164 * a canonical native form. */
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;
169
170 /* [De]Initialisation handlers. */
171 int (*init)(DSO *dso);
172 int (*finish)(DSO *dso);
173 } DSO_METHOD;
174
175/**********************************************************************/
176/* The low-level handle type used to refer to a loaded shared library */
177
178struct dso_st
179 {
180 DSO_METHOD *meth;
181 /* Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS
182 * doesn't use anything but will need to cache the filename
183 * for use in the dso_bind handler. All in all, let each
184 * method control its own destiny. "Handles" and such go in
185 * a STACK. */
186 STACK *meth_data;
187 int references;
188 int flags;
189 /* For use by applications etc ... use this for your bits'n'pieces,
190 * don't touch meth_data! */
191 CRYPTO_EX_DATA ex_data;
192 /* If this callback function pointer is set to non-NULL, then it will
193 * be used in DSO_load() in place of meth->dso_name_converter. NB: This
194 * should normally set using DSO_set_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;
200 /* This is populated with (a copy of) the platform-independant
201 * filename used for this DSO. */
202 char *filename;
203 /* This is populated with (a copy of) the translated filename by which
204 * the DSO was actually loaded. It is NULL iff the DSO is not currently
205 * loaded. NB: This is here because the filename translation process
206 * may involve a callback being invoked more than once not only to
207 * convert to a platform-specific form, but also to try different
208 * filenames in the process of trying to perform a load. As such, this
209 * variable can be used to indicate (a) whether this DSO structure
210 * corresponds to a loaded library or not, and (b) the filename with
211 * which it was actually loaded. */
212 char *loaded_filename;
213 };
214
215
216DSO * DSO_new(void);
217DSO * DSO_new_method(DSO_METHOD *method);
218int DSO_free(DSO *dso);
219int DSO_flags(DSO *dso);
220int DSO_up_ref(DSO *dso);
221long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);
222
223/* This function sets the DSO's name_converter callback. If it is non-NULL,
224 * then it will be used instead of the associated DSO_METHOD's function. If
225 * oldcb is non-NULL then it is set to the function pointer value being
226 * replaced. Return value is non-zero for success. */
227int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
228 DSO_NAME_CONVERTER_FUNC *oldcb);
229/* These functions can be used to get/set the platform-independant filename
230 * used for a DSO. NB: set will fail if the DSO is already loaded. */
231const char *DSO_get_filename(DSO *dso);
232int DSO_set_filename(DSO *dso, const char *filename);
233/* This function will invoke the DSO's name_converter callback to translate a
234 * filename, or if the callback isn't set it will instead use the DSO_METHOD's
235 * converter. If "filename" is NULL, the "filename" in the DSO itself will be
236 * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is
237 * simply duplicated. NB: This function is usually called from within a
238 * DSO_METHOD during the processing of a DSO_load() call, and is exposed so that
239 * caller-created DSO_METHODs can do the same thing. A non-NULL return value
240 * will need to be OPENSSL_free()'d. */
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);
247/* If the DSO is currently loaded, this returns the filename that it was loaded
248 * under, otherwise it returns NULL. So it is also useful as a test as to
249 * whether the DSO is currently loaded. NB: This will not necessarily return
250 * the same value as DSO_convert_filename(dso, dso->filename), because the
251 * DSO_METHOD's load function may have tried a variety of filenames (with
252 * and/or without the aid of the converters) before settling on the one it
253 * actually loaded. */
254const char *DSO_get_loaded_filename(DSO *dso);
255
256void DSO_set_default_method(DSO_METHOD *meth);
257DSO_METHOD *DSO_get_default_method(void);
258DSO_METHOD *DSO_get_method(DSO *dso);
259DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);
260
261/* The all-singing all-dancing load function, you normally pass NULL
262 * for the first and third parameters. Use DSO_up and DSO_free for
263 * subsequent reference count handling. Any flags passed in will be set
264 * in the constructed DSO after its init() function but before the
265 * load operation. If 'dso' is non-NULL, 'flags' is ignored. */
266DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);
267
268/* This function binds to a variable inside a shared library. */
269void *DSO_bind_var(DSO *dso, const char *symname);
270
271/* This function binds to a function inside a shared library. */
272DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname);
273
274/* This method is the default, but will beg, borrow, or steal whatever
275 * method should be the default on any particular platform (including
276 * DSO_METH_null() if necessary). */
277DSO_METHOD *DSO_METHOD_openssl(void);
278
279/* This method is defined for all platforms - if a platform has no
280 * DSO support then this will be the only method! */
281DSO_METHOD *DSO_METHOD_null(void);
282
283/* If DSO_DLFCN is defined, the standard dlfcn.h-style functions
284 * (dlopen, dlclose, dlsym, etc) will be used and incorporated into
285 * this method. If not, this method will return NULL. */
286DSO_METHOD *DSO_METHOD_dlfcn(void);
287
288/* If DSO_DL is defined, the standard dl.h-style functions (shl_load,
289 * shl_unload, shl_findsym, etc) will be used and incorporated into
290 * this method. If not, this method will return NULL. */
291DSO_METHOD *DSO_METHOD_dl(void);
292
293/* If WIN32 is defined, use DLLs. If not, return NULL. */
294DSO_METHOD *DSO_METHOD_win32(void);
295
296/* If VMS is defined, use shared images. If not, return NULL. */
297DSO_METHOD *DSO_METHOD_vms(void);
298
299/* BEGIN ERROR CODES */
300/* The following lines are auto generated by the script mkerr.pl. Any changes
301 * made after this point may be overwritten when the script is next run.
302 */
303void ERR_load_DSO_strings(void);
304
305/* Error codes for the DSO functions. */
306
307/* Function codes. */
308#define DSO_F_DLFCN_BIND_FUNC 100
309#define DSO_F_DLFCN_BIND_VAR 101
310#define DSO_F_DLFCN_LOAD 102
311#define DSO_F_DLFCN_MERGER 130
312#define DSO_F_DLFCN_NAME_CONVERTER 123
313#define DSO_F_DLFCN_UNLOAD 103
314#define DSO_F_DL_BIND_FUNC 104
315#define DSO_F_DL_BIND_VAR 105
316#define DSO_F_DL_LOAD 106
317#define DSO_F_DL_MERGER 131
318#define DSO_F_DL_NAME_CONVERTER 124
319#define DSO_F_DL_UNLOAD 107
320#define DSO_F_DSO_BIND_FUNC 108
321#define DSO_F_DSO_BIND_VAR 109
322#define DSO_F_DSO_CONVERT_FILENAME 126
323#define DSO_F_DSO_CTRL 110
324#define DSO_F_DSO_FREE 111
325#define DSO_F_DSO_GET_FILENAME 127
326#define DSO_F_DSO_GET_LOADED_FILENAME 128
327#define DSO_F_DSO_LOAD 112
328#define DSO_F_DSO_MERGE 132
329#define DSO_F_DSO_NEW_METHOD 113
330#define DSO_F_DSO_SET_FILENAME 129
331#define DSO_F_DSO_SET_NAME_CONVERTER 122
332#define DSO_F_DSO_UP_REF 114
333#define DSO_F_VMS_BIND_SYM 115
334#define DSO_F_VMS_LOAD 116
335#define DSO_F_VMS_MERGER 133
336#define DSO_F_VMS_UNLOAD 117
337#define DSO_F_WIN32_BIND_FUNC 118
338#define DSO_F_WIN32_BIND_VAR 119
339#define DSO_F_WIN32_JOINER 135
340#define DSO_F_WIN32_LOAD 120
341#define DSO_F_WIN32_MERGER 134
342#define DSO_F_WIN32_NAME_CONVERTER 125
343#define DSO_F_WIN32_SPLITTER 136
344#define DSO_F_WIN32_UNLOAD 121
345
346/* Reason codes. */
347#define DSO_R_CTRL_FAILED 100
348#define DSO_R_DSO_ALREADY_LOADED 110
349#define DSO_R_EMPTY_FILE_STRUCTURE 113
350#define DSO_R_FAILURE 114
351#define DSO_R_FILENAME_TOO_BIG 101
352#define DSO_R_FINISH_FAILED 102
353#define DSO_R_INCORRECT_FILE_SYNTAX 115
354#define DSO_R_LOAD_FAILED 103
355#define DSO_R_NAME_TRANSLATION_FAILED 109
356#define DSO_R_NO_FILENAME 111
357#define DSO_R_NO_FILE_SPECIFICATION 116
358#define DSO_R_NULL_HANDLE 104
359#define DSO_R_SET_FILENAME_FAILED 112
360#define DSO_R_STACK_ERROR 105
361#define DSO_R_SYM_FAILURE 106
362#define DSO_R_UNLOAD_FAILED 107
363#define DSO_R_UNSUPPORTED 108
364
365#ifdef __cplusplus
366}
367#endif
368#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..417abb6ea9
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_dl.c
@@ -0,0 +1,353 @@
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);
88
89static DSO_METHOD dso_meth_dl = {
90 "OpenSSL 'dl' shared library method",
91 dl_load,
92 dl_unload,
93 dl_bind_var,
94 dl_bind_func,
95/* For now, "unbind" doesn't exist */
96#if 0
97 NULL, /* unbind_var */
98 NULL, /* unbind_func */
99#endif
100 NULL, /* ctrl */
101 dl_name_converter,
102 dl_merger,
103 NULL, /* init */
104 NULL /* finish */
105 };
106
107DSO_METHOD *DSO_METHOD_dl(void)
108 {
109 return(&dso_meth_dl);
110 }
111
112/* For this DSO_METHOD, our meth_data STACK will contain;
113 * (i) the handle (shl_t) returned from shl_load().
114 * NB: I checked on HPUX11 and shl_t is itself a pointer
115 * type so the cast is safe.
116 */
117
118static int dl_load(DSO *dso)
119 {
120 shl_t ptr = NULL;
121 /* We don't do any fancy retries or anything, just take the method's
122 * (or DSO's if it has the callback set) best translation of the
123 * platform-independant filename and try once with that. */
124 char *filename= DSO_convert_filename(dso, NULL);
125
126 if(filename == NULL)
127 {
128 DSOerr(DSO_F_DL_LOAD,DSO_R_NO_FILENAME);
129 goto err;
130 }
131 ptr = shl_load(filename, BIND_IMMEDIATE |
132 (dso->flags&DSO_FLAG_NO_NAME_TRANSLATION?0:DYNAMIC_PATH), 0L);
133 if(ptr == NULL)
134 {
135 DSOerr(DSO_F_DL_LOAD,DSO_R_LOAD_FAILED);
136 ERR_add_error_data(4, "filename(", filename, "): ",
137 strerror(errno));
138 goto err;
139 }
140 if(!sk_push(dso->meth_data, (char *)ptr))
141 {
142 DSOerr(DSO_F_DL_LOAD,DSO_R_STACK_ERROR);
143 goto err;
144 }
145 /* Success, stick the converted filename we've loaded under into the DSO
146 * (it also serves as the indicator that we are currently loaded). */
147 dso->loaded_filename = filename;
148 return(1);
149err:
150 /* Cleanup! */
151 if(filename != NULL)
152 OPENSSL_free(filename);
153 if(ptr != NULL)
154 shl_unload(ptr);
155 return(0);
156 }
157
158static int dl_unload(DSO *dso)
159 {
160 shl_t ptr;
161 if(dso == NULL)
162 {
163 DSOerr(DSO_F_DL_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
164 return(0);
165 }
166 if(sk_num(dso->meth_data) < 1)
167 return(1);
168 /* Is this statement legal? */
169 ptr = (shl_t)sk_pop(dso->meth_data);
170 if(ptr == NULL)
171 {
172 DSOerr(DSO_F_DL_UNLOAD,DSO_R_NULL_HANDLE);
173 /* Should push the value back onto the stack in
174 * case of a retry. */
175 sk_push(dso->meth_data, (char *)ptr);
176 return(0);
177 }
178 shl_unload(ptr);
179 return(1);
180 }
181
182static void *dl_bind_var(DSO *dso, const char *symname)
183 {
184 shl_t ptr;
185 void *sym;
186
187 if((dso == NULL) || (symname == NULL))
188 {
189 DSOerr(DSO_F_DL_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
190 return(NULL);
191 }
192 if(sk_num(dso->meth_data) < 1)
193 {
194 DSOerr(DSO_F_DL_BIND_VAR,DSO_R_STACK_ERROR);
195 return(NULL);
196 }
197 ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
198 if(ptr == NULL)
199 {
200 DSOerr(DSO_F_DL_BIND_VAR,DSO_R_NULL_HANDLE);
201 return(NULL);
202 }
203 if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0)
204 {
205 DSOerr(DSO_F_DL_BIND_VAR,DSO_R_SYM_FAILURE);
206 ERR_add_error_data(4, "symname(", symname, "): ",
207 strerror(errno));
208 return(NULL);
209 }
210 return(sym);
211 }
212
213static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
214 {
215 shl_t ptr;
216 void *sym;
217
218 if((dso == NULL) || (symname == NULL))
219 {
220 DSOerr(DSO_F_DL_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
221 return(NULL);
222 }
223 if(sk_num(dso->meth_data) < 1)
224 {
225 DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_STACK_ERROR);
226 return(NULL);
227 }
228 ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
229 if(ptr == NULL)
230 {
231 DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_NULL_HANDLE);
232 return(NULL);
233 }
234 if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0)
235 {
236 DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_SYM_FAILURE);
237 ERR_add_error_data(4, "symname(", symname, "): ",
238 strerror(errno));
239 return(NULL);
240 }
241 return((DSO_FUNC_TYPE)sym);
242 }
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
310/* This function is identical to the one in dso_dlfcn.c, but as it is highly
311 * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at the
312 * same time, there's no great duplicating the code. Figuring out an elegant
313 * way to share one copy of the code would be more difficult and would not
314 * leave the implementations independant. */
315#if defined(__hpux)
316static const char extension[] = ".sl";
317#else
318static const char extension[] = ".so";
319#endif
320static char *dl_name_converter(DSO *dso, const char *filename)
321 {
322 char *translated;
323 int len, rsize, transform;
324
325 len = strlen(filename);
326 rsize = len + 1;
327 transform = (strstr(filename, "/") == NULL);
328 {
329 /* We will convert this to "%s.s?" or "lib%s.s?" */
330 rsize += strlen(extension);/* The length of ".s?" */
331 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
332 rsize += 3; /* The length of "lib" */
333 }
334 translated = OPENSSL_malloc(rsize);
335 if(translated == NULL)
336 {
337 DSOerr(DSO_F_DL_NAME_CONVERTER,
338 DSO_R_NAME_TRANSLATION_FAILED);
339 return(NULL);
340 }
341 if(transform)
342 {
343 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
344 sprintf(translated, "lib%s%s", filename, extension);
345 else
346 sprintf(translated, "%s%s", filename, extension);
347 }
348 else
349 sprintf(translated, "%s", filename);
350 return(translated);
351 }
352
353#endif /* DSO_DL */
diff --git a/src/lib/libcrypto/dso/dso_dlfcn.c b/src/lib/libcrypto/dso/dso_dlfcn.c
new file mode 100644
index 0000000000..656cd496f8
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_dlfcn.c
@@ -0,0 +1,372 @@
1/* dso_dlfcn.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 "cryptlib.h"
61#include <openssl/dso.h>
62
63#ifndef DSO_DLFCN
64DSO_METHOD *DSO_METHOD_dlfcn(void)
65 {
66 return NULL;
67 }
68#else
69
70#ifdef HAVE_DLFCN_H
71#include <dlfcn.h>
72#endif
73
74/* Part of the hack in "dlfcn_load" ... */
75#define DSO_MAX_TRANSLATED_SIZE 256
76
77static int dlfcn_load(DSO *dso);
78static int dlfcn_unload(DSO *dso);
79static void *dlfcn_bind_var(DSO *dso, const char *symname);
80static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
81#if 0
82static int dlfcn_unbind(DSO *dso, char *symname, void *symptr);
83static int dlfcn_init(DSO *dso);
84static int dlfcn_finish(DSO *dso);
85static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
86#endif
87static char *dlfcn_name_converter(DSO *dso, const char *filename);
88static char *dlfcn_merger(DSO *dso, const char *filespec1,
89 const char *filespec2);
90
91static DSO_METHOD dso_meth_dlfcn = {
92 "OpenSSL 'dlfcn' shared library method",
93 dlfcn_load,
94 dlfcn_unload,
95 dlfcn_bind_var,
96 dlfcn_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 dlfcn_name_converter,
104 dlfcn_merger,
105 NULL, /* init */
106 NULL /* finish */
107 };
108
109DSO_METHOD *DSO_METHOD_dlfcn(void)
110 {
111 return(&dso_meth_dlfcn);
112 }
113
114/* Prior to using the dlopen() function, we should decide on the flag
115 * we send. There's a few different ways of doing this and it's a
116 * messy venn-diagram to match up which platforms support what. So
117 * as we don't have autoconf yet, I'm implementing a hack that could
118 * be hacked further relatively easily to deal with cases as we find
119 * them. Initially this is to cope with OpenBSD. */
120#if defined(__OpenBSD__) || defined(__NetBSD__)
121# ifdef DL_LAZY
122# define DLOPEN_FLAG DL_LAZY
123# else
124# ifdef RTLD_NOW
125# define DLOPEN_FLAG RTLD_NOW
126# else
127# define DLOPEN_FLAG 0
128# endif
129# endif
130#else
131# ifdef OPENSSL_SYS_SUNOS
132# define DLOPEN_FLAG 1
133# else
134# define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */
135# endif
136#endif
137
138/* For this DSO_METHOD, our meth_data STACK will contain;
139 * (i) the handle (void*) returned from dlopen().
140 */
141
142static int dlfcn_load(DSO *dso)
143 {
144 void *ptr = NULL;
145 /* See applicable comments in dso_dl.c */
146 char *filename = DSO_convert_filename(dso, NULL);
147 int flags = DLOPEN_FLAG;
148
149 if(filename == NULL)
150 {
151 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME);
152 goto err;
153 }
154
155#ifdef RTLD_GLOBAL
156 if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
157 flags |= RTLD_GLOBAL;
158#endif
159 ptr = dlopen(filename, flags);
160 if(ptr == NULL)
161 {
162 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
163 ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
164 goto err;
165 }
166 if(!sk_push(dso->meth_data, (char *)ptr))
167 {
168 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR);
169 goto err;
170 }
171 /* Success */
172 dso->loaded_filename = filename;
173 return(1);
174err:
175 /* Cleanup! */
176 if(filename != NULL)
177 OPENSSL_free(filename);
178 if(ptr != NULL)
179 dlclose(ptr);
180 return(0);
181}
182
183static int dlfcn_unload(DSO *dso)
184 {
185 void *ptr;
186 if(dso == NULL)
187 {
188 DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
189 return(0);
190 }
191 if(sk_num(dso->meth_data) < 1)
192 return(1);
193 ptr = (void *)sk_pop(dso->meth_data);
194 if(ptr == NULL)
195 {
196 DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE);
197 /* Should push the value back onto the stack in
198 * case of a retry. */
199 sk_push(dso->meth_data, (char *)ptr);
200 return(0);
201 }
202 /* For now I'm not aware of any errors associated with dlclose() */
203 dlclose(ptr);
204 return(1);
205 }
206
207static void *dlfcn_bind_var(DSO *dso, const char *symname)
208 {
209 void *ptr, *sym;
210
211 if((dso == NULL) || (symname == NULL))
212 {
213 DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
214 return(NULL);
215 }
216 if(sk_num(dso->meth_data) < 1)
217 {
218 DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR);
219 return(NULL);
220 }
221 ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
222 if(ptr == NULL)
223 {
224 DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE);
225 return(NULL);
226 }
227 sym = dlsym(ptr, symname);
228 if(sym == NULL)
229 {
230 DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_SYM_FAILURE);
231 ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
232 return(NULL);
233 }
234 return(sym);
235 }
236
237static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
238 {
239 void *ptr;
240 DSO_FUNC_TYPE sym, *tsym = &sym;
241
242 if((dso == NULL) || (symname == NULL))
243 {
244 DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
245 return(NULL);
246 }
247 if(sk_num(dso->meth_data) < 1)
248 {
249 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR);
250 return(NULL);
251 }
252 ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
253 if(ptr == NULL)
254 {
255 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
256 return(NULL);
257 }
258 *(void **)(tsym) = dlsym(ptr, symname);
259 if(sym == NULL)
260 {
261 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
262 ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
263 return(NULL);
264 }
265 return(sym);
266 }
267
268static char *dlfcn_merger(DSO *dso, const char *filespec1,
269 const char *filespec2)
270 {
271 char *merged;
272 size_t len;
273
274 if(!filespec1 && !filespec2)
275 {
276 DSOerr(DSO_F_DLFCN_MERGER,
277 ERR_R_PASSED_NULL_PARAMETER);
278 return(NULL);
279 }
280 /* If the first file specification is a rooted path, it rules.
281 same goes if the second file specification is missing. */
282 if (!filespec2 || filespec1[0] == '/')
283 {
284 len = strlen(filespec1) + 1;
285 merged = OPENSSL_malloc(len);
286 if(!merged)
287 {
288 DSOerr(DSO_F_DLFCN_MERGER,
289 ERR_R_MALLOC_FAILURE);
290 return(NULL);
291 }
292 strlcpy(merged, filespec1, len);
293 }
294 /* If the first file specification is missing, the second one rules. */
295 else if (!filespec1)
296 {
297 len = strlen(filespec2) + 1;
298 merged = OPENSSL_malloc(strlen(filespec2) + 1);
299 if(!merged)
300 {
301 DSOerr(DSO_F_DLFCN_MERGER,
302 ERR_R_MALLOC_FAILURE);
303 return(NULL);
304 }
305 strlcpy(merged, filespec2, len);
306 }
307 else
308 /* This part isn't as trivial as it looks. It assumes that
309 the second file specification really is a directory, and
310 makes no checks whatsoever. Therefore, the result becomes
311 the concatenation of filespec2 followed by a slash followed
312 by filespec1. */
313 {
314 int spec2len, len;
315
316 spec2len = (filespec2 ? strlen(filespec2) : 0);
317 len = spec2len + (filespec1 ? strlen(filespec1) : 0);
318
319 if(filespec2 && filespec2[spec2len - 1] == '/')
320 {
321 spec2len--;
322 len--;
323 }
324 merged = OPENSSL_malloc(len + 2);
325 if(!merged)
326 {
327 DSOerr(DSO_F_DLFCN_MERGER,
328 ERR_R_MALLOC_FAILURE);
329 return(NULL);
330 }
331 strlcpy(merged, filespec2, len + 2);
332 merged[spec2len] = '/';
333 strlcpy(&merged[spec2len + 1], filespec1, len + 1 - spec2len);
334 }
335 return(merged);
336 }
337
338static char *dlfcn_name_converter(DSO *dso, const char *filename)
339 {
340 char *translated;
341 int len, rsize, transform;
342
343 len = strlen(filename);
344 rsize = len + 1;
345 transform = (strstr(filename, "/") == NULL);
346 if(transform)
347 {
348 /* We will convert this to "%s.so" or "lib%s.so" */
349 rsize += 3; /* The length of ".so" */
350 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
351 rsize += 3; /* The length of "lib" */
352 }
353 translated = OPENSSL_malloc(rsize);
354 if(translated == NULL)
355 {
356 DSOerr(DSO_F_DLFCN_NAME_CONVERTER,
357 DSO_R_NAME_TRANSLATION_FAILED);
358 return(NULL);
359 }
360 if(transform)
361 {
362 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
363 snprintf(translated, rsize, "lib%s.so", filename);
364 else
365 snprintf(translated, rsize, "%s.so", filename);
366 }
367 else
368 snprintf(translated, rsize, "%s", filename);
369 return(translated);
370 }
371
372#endif /* DSO_DLFCN */
diff --git a/src/lib/libcrypto/dso/dso_err.c b/src/lib/libcrypto/dso/dso_err.c
new file mode 100644
index 0000000000..a8b0a210de
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_err.c
@@ -0,0 +1,147 @@
1/* crypto/dso/dso_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include <openssl/dso.h>
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67
68#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSO,func,0)
69#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSO,0,reason)
70
71static ERR_STRING_DATA DSO_str_functs[]=
72 {
73{ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "DLFCN_BIND_FUNC"},
74{ERR_FUNC(DSO_F_DLFCN_BIND_VAR), "DLFCN_BIND_VAR"},
75{ERR_FUNC(DSO_F_DLFCN_LOAD), "DLFCN_LOAD"},
76{ERR_FUNC(DSO_F_DLFCN_MERGER), "DLFCN_MERGER"},
77{ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER), "DLFCN_NAME_CONVERTER"},
78{ERR_FUNC(DSO_F_DLFCN_UNLOAD), "DLFCN_UNLOAD"},
79{ERR_FUNC(DSO_F_DL_BIND_FUNC), "DL_BIND_FUNC"},
80{ERR_FUNC(DSO_F_DL_BIND_VAR), "DL_BIND_VAR"},
81{ERR_FUNC(DSO_F_DL_LOAD), "DL_LOAD"},
82{ERR_FUNC(DSO_F_DL_MERGER), "DL_MERGER"},
83{ERR_FUNC(DSO_F_DL_NAME_CONVERTER), "DL_NAME_CONVERTER"},
84{ERR_FUNC(DSO_F_DL_UNLOAD), "DL_UNLOAD"},
85{ERR_FUNC(DSO_F_DSO_BIND_FUNC), "DSO_bind_func"},
86{ERR_FUNC(DSO_F_DSO_BIND_VAR), "DSO_bind_var"},
87{ERR_FUNC(DSO_F_DSO_CONVERT_FILENAME), "DSO_convert_filename"},
88{ERR_FUNC(DSO_F_DSO_CTRL), "DSO_ctrl"},
89{ERR_FUNC(DSO_F_DSO_FREE), "DSO_free"},
90{ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"},
91{ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME), "DSO_get_loaded_filename"},
92{ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"},
93{ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"},
94{ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"},
95{ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"},
96{ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER), "DSO_set_name_converter"},
97{ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"},
98{ERR_FUNC(DSO_F_VMS_BIND_SYM), "VMS_BIND_SYM"},
99{ERR_FUNC(DSO_F_VMS_LOAD), "VMS_LOAD"},
100{ERR_FUNC(DSO_F_VMS_MERGER), "VMS_MERGER"},
101{ERR_FUNC(DSO_F_VMS_UNLOAD), "VMS_UNLOAD"},
102{ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "WIN32_BIND_FUNC"},
103{ERR_FUNC(DSO_F_WIN32_BIND_VAR), "WIN32_BIND_VAR"},
104{ERR_FUNC(DSO_F_WIN32_JOINER), "WIN32_JOINER"},
105{ERR_FUNC(DSO_F_WIN32_LOAD), "WIN32_LOAD"},
106{ERR_FUNC(DSO_F_WIN32_MERGER), "WIN32_MERGER"},
107{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"},
108{ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"},
109{ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"},
110{0,NULL}
111 };
112
113static ERR_STRING_DATA DSO_str_reasons[]=
114 {
115{ERR_REASON(DSO_R_CTRL_FAILED) ,"control command failed"},
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"},
119{ERR_REASON(DSO_R_FILENAME_TOO_BIG) ,"filename too big"},
120{ERR_REASON(DSO_R_FINISH_FAILED) ,"cleanup method function failed"},
121{ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX) ,"incorrect file syntax"},
122{ERR_REASON(DSO_R_LOAD_FAILED) ,"could not load the shared library"},
123{ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED),"name translation failed"},
124{ERR_REASON(DSO_R_NO_FILENAME) ,"no filename"},
125{ERR_REASON(DSO_R_NO_FILE_SPECIFICATION) ,"no file specification"},
126{ERR_REASON(DSO_R_NULL_HANDLE) ,"a null shared library handle was used"},
127{ERR_REASON(DSO_R_SET_FILENAME_FAILED) ,"set filename failed"},
128{ERR_REASON(DSO_R_STACK_ERROR) ,"the meth_data stack is corrupt"},
129{ERR_REASON(DSO_R_SYM_FAILURE) ,"could not bind to the requested symbol name"},
130{ERR_REASON(DSO_R_UNLOAD_FAILED) ,"could not unload the shared library"},
131{ERR_REASON(DSO_R_UNSUPPORTED) ,"functionality not supported"},
132{0,NULL}
133 };
134
135#endif
136
137void ERR_load_DSO_strings(void)
138 {
139#ifndef OPENSSL_NO_ERR
140
141 if (ERR_func_error_string(DSO_str_functs[0].error) == NULL)
142 {
143 ERR_load_strings(0,DSO_str_functs);
144 ERR_load_strings(0,DSO_str_reasons);
145 }
146#endif
147 }
diff --git a/src/lib/libcrypto/dso/dso_lib.c b/src/lib/libcrypto/dso/dso_lib.c
new file mode 100644
index 0000000000..49bdd71309
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_lib.c
@@ -0,0 +1,466 @@
1/* dso_lib.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 <openssl/crypto.h>
61#include "cryptlib.h"
62#include <openssl/dso.h>
63
64static DSO_METHOD *default_DSO_meth = NULL;
65
66DSO *DSO_new(void)
67 {
68 return(DSO_new_method(NULL));
69 }
70
71void DSO_set_default_method(DSO_METHOD *meth)
72 {
73 default_DSO_meth = meth;
74 }
75
76DSO_METHOD *DSO_get_default_method(void)
77 {
78 return(default_DSO_meth);
79 }
80
81DSO_METHOD *DSO_get_method(DSO *dso)
82 {
83 return(dso->meth);
84 }
85
86DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth)
87 {
88 DSO_METHOD *mtmp;
89 mtmp = dso->meth;
90 dso->meth = meth;
91 return(mtmp);
92 }
93
94DSO *DSO_new_method(DSO_METHOD *meth)
95 {
96 DSO *ret;
97
98 if(default_DSO_meth == NULL)
99 /* We default to DSO_METH_openssl() which in turn defaults
100 * to stealing the "best available" method. Will fallback
101 * to DSO_METH_null() in the worst case. */
102 default_DSO_meth = DSO_METHOD_openssl();
103 ret = (DSO *)OPENSSL_malloc(sizeof(DSO));
104 if(ret == NULL)
105 {
106 DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE);
107 return(NULL);
108 }
109 memset(ret, 0, sizeof(DSO));
110 ret->meth_data = sk_new_null();
111 if(ret->meth_data == NULL)
112 {
113 /* sk_new doesn't generate any errors so we do */
114 DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE);
115 OPENSSL_free(ret);
116 return(NULL);
117 }
118 if(meth == NULL)
119 ret->meth = default_DSO_meth;
120 else
121 ret->meth = meth;
122 ret->references = 1;
123 if((ret->meth->init != NULL) && !ret->meth->init(ret))
124 {
125 OPENSSL_free(ret);
126 ret=NULL;
127 }
128 return(ret);
129 }
130
131int DSO_free(DSO *dso)
132 {
133 int i;
134
135 if(dso == NULL)
136 {
137 DSOerr(DSO_F_DSO_FREE,ERR_R_PASSED_NULL_PARAMETER);
138 return(0);
139 }
140
141 i=CRYPTO_add(&dso->references,-1,CRYPTO_LOCK_DSO);
142#ifdef REF_PRINT
143 REF_PRINT("DSO",dso);
144#endif
145 if(i > 0) return(1);
146#ifdef REF_CHECK
147 if(i < 0)
148 {
149 fprintf(stderr,"DSO_free, bad reference count\n");
150 abort();
151 }
152#endif
153
154 if((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso))
155 {
156 DSOerr(DSO_F_DSO_FREE,DSO_R_UNLOAD_FAILED);
157 return(0);
158 }
159
160 if((dso->meth->finish != NULL) && !dso->meth->finish(dso))
161 {
162 DSOerr(DSO_F_DSO_FREE,DSO_R_FINISH_FAILED);
163 return(0);
164 }
165
166 sk_free(dso->meth_data);
167 if(dso->filename != NULL)
168 OPENSSL_free(dso->filename);
169 if(dso->loaded_filename != NULL)
170 OPENSSL_free(dso->loaded_filename);
171
172 OPENSSL_free(dso);
173 return(1);
174 }
175
176int DSO_flags(DSO *dso)
177 {
178 return((dso == NULL) ? 0 : dso->flags);
179 }
180
181
182int DSO_up_ref(DSO *dso)
183 {
184 if (dso == NULL)
185 {
186 DSOerr(DSO_F_DSO_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
187 return(0);
188 }
189
190 CRYPTO_add(&dso->references,1,CRYPTO_LOCK_DSO);
191 return(1);
192 }
193
194DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
195 {
196 DSO *ret;
197 int allocated = 0;
198
199 if(dso == NULL)
200 {
201 ret = DSO_new_method(meth);
202 if(ret == NULL)
203 {
204 DSOerr(DSO_F_DSO_LOAD,ERR_R_MALLOC_FAILURE);
205 goto err;
206 }
207 allocated = 1;
208 /* Pass the provided flags to the new DSO object */
209 if(DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0)
210 {
211 DSOerr(DSO_F_DSO_LOAD,DSO_R_CTRL_FAILED);
212 goto err;
213 }
214 }
215 else
216 ret = dso;
217 /* Don't load if we're currently already loaded */
218 if(ret->filename != NULL)
219 {
220 DSOerr(DSO_F_DSO_LOAD,DSO_R_DSO_ALREADY_LOADED);
221 goto err;
222 }
223 /* filename can only be NULL if we were passed a dso that already has
224 * one set. */
225 if(filename != NULL)
226 if(!DSO_set_filename(ret, filename))
227 {
228 DSOerr(DSO_F_DSO_LOAD,DSO_R_SET_FILENAME_FAILED);
229 goto err;
230 }
231 filename = ret->filename;
232 if(filename == NULL)
233 {
234 DSOerr(DSO_F_DSO_LOAD,DSO_R_NO_FILENAME);
235 goto err;
236 }
237 if(ret->meth->dso_load == NULL)
238 {
239 DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED);
240 goto err;
241 }
242 if(!ret->meth->dso_load(ret))
243 {
244 DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED);
245 goto err;
246 }
247 /* Load succeeded */
248 return(ret);
249err:
250 if(allocated)
251 DSO_free(ret);
252 return(NULL);
253 }
254
255void *DSO_bind_var(DSO *dso, const char *symname)
256 {
257 void *ret = NULL;
258
259 if((dso == NULL) || (symname == NULL))
260 {
261 DSOerr(DSO_F_DSO_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
262 return(NULL);
263 }
264 if(dso->meth->dso_bind_var == NULL)
265 {
266 DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_UNSUPPORTED);
267 return(NULL);
268 }
269 if((ret = dso->meth->dso_bind_var(dso, symname)) == NULL)
270 {
271 DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_SYM_FAILURE);
272 return(NULL);
273 }
274 /* Success */
275 return(ret);
276 }
277
278DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
279 {
280 DSO_FUNC_TYPE ret = NULL;
281
282 if((dso == NULL) || (symname == NULL))
283 {
284 DSOerr(DSO_F_DSO_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
285 return(NULL);
286 }
287 if(dso->meth->dso_bind_func == NULL)
288 {
289 DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_UNSUPPORTED);
290 return(NULL);
291 }
292 if((ret = dso->meth->dso_bind_func(dso, symname)) == NULL)
293 {
294 DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_SYM_FAILURE);
295 return(NULL);
296 }
297 /* Success */
298 return(ret);
299 }
300
301/* I don't really like these *_ctrl functions very much to be perfectly
302 * honest. For one thing, I think I have to return a negative value for
303 * any error because possible DSO_ctrl() commands may return values
304 * such as "size"s that can legitimately be zero (making the standard
305 * "if(DSO_cmd(...))" form that works almost everywhere else fail at
306 * odd times. I'd prefer "output" values to be passed by reference and
307 * the return value as success/failure like usual ... but we conform
308 * when we must... :-) */
309long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
310 {
311 if(dso == NULL)
312 {
313 DSOerr(DSO_F_DSO_CTRL,ERR_R_PASSED_NULL_PARAMETER);
314 return(-1);
315 }
316 /* We should intercept certain generic commands and only pass control
317 * to the method-specific ctrl() function if it's something we don't
318 * handle. */
319 switch(cmd)
320 {
321 case DSO_CTRL_GET_FLAGS:
322 return dso->flags;
323 case DSO_CTRL_SET_FLAGS:
324 dso->flags = (int)larg;
325 return(0);
326 case DSO_CTRL_OR_FLAGS:
327 dso->flags |= (int)larg;
328 return(0);
329 default:
330 break;
331 }
332 if((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL))
333 {
334 DSOerr(DSO_F_DSO_CTRL,DSO_R_UNSUPPORTED);
335 return(-1);
336 }
337 return(dso->meth->dso_ctrl(dso,cmd,larg,parg));
338 }
339
340int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
341 DSO_NAME_CONVERTER_FUNC *oldcb)
342 {
343 if(dso == NULL)
344 {
345 DSOerr(DSO_F_DSO_SET_NAME_CONVERTER,
346 ERR_R_PASSED_NULL_PARAMETER);
347 return(0);
348 }
349 if(oldcb)
350 *oldcb = dso->name_converter;
351 dso->name_converter = cb;
352 return(1);
353 }
354
355const char *DSO_get_filename(DSO *dso)
356 {
357 if(dso == NULL)
358 {
359 DSOerr(DSO_F_DSO_GET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
360 return(NULL);
361 }
362 return(dso->filename);
363 }
364
365int DSO_set_filename(DSO *dso, const char *filename)
366 {
367 char *copied;
368
369 if((dso == NULL) || (filename == NULL))
370 {
371 DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
372 return(0);
373 }
374 if(dso->loaded_filename)
375 {
376 DSOerr(DSO_F_DSO_SET_FILENAME,DSO_R_DSO_ALREADY_LOADED);
377 return(0);
378 }
379 /* We'll duplicate filename */
380 copied = OPENSSL_malloc(strlen(filename) + 1);
381 if(copied == NULL)
382 {
383 DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_MALLOC_FAILURE);
384 return(0);
385 }
386 BUF_strlcpy(copied, filename, strlen(filename) + 1);
387 if(dso->filename)
388 OPENSSL_free(dso->filename);
389 dso->filename = copied;
390 return(1);
391 }
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
420char *DSO_convert_filename(DSO *dso, const char *filename)
421 {
422 char *result = NULL;
423
424 if(dso == NULL)
425 {
426 DSOerr(DSO_F_DSO_CONVERT_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
427 return(NULL);
428 }
429 if(filename == NULL)
430 filename = dso->filename;
431 if(filename == NULL)
432 {
433 DSOerr(DSO_F_DSO_CONVERT_FILENAME,DSO_R_NO_FILENAME);
434 return(NULL);
435 }
436 if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
437 {
438 if(dso->name_converter != NULL)
439 result = dso->name_converter(dso, filename);
440 else if(dso->meth->dso_name_converter != NULL)
441 result = dso->meth->dso_name_converter(dso, filename);
442 }
443 if(result == NULL)
444 {
445 result = OPENSSL_malloc(strlen(filename) + 1);
446 if(result == NULL)
447 {
448 DSOerr(DSO_F_DSO_CONVERT_FILENAME,
449 ERR_R_MALLOC_FAILURE);
450 return(NULL);
451 }
452 BUF_strlcpy(result, filename, strlen(filename) + 1);
453 }
454 return(result);
455 }
456
457const char *DSO_get_loaded_filename(DSO *dso)
458 {
459 if(dso == NULL)
460 {
461 DSOerr(DSO_F_DSO_GET_LOADED_FILENAME,
462 ERR_R_PASSED_NULL_PARAMETER);
463 return(NULL);
464 }
465 return(dso->loaded_filename);
466 }
diff --git a/src/lib/libcrypto/dso/dso_null.c b/src/lib/libcrypto/dso/dso_null.c
new file mode 100644
index 0000000000..4972984651
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_null.c
@@ -0,0 +1,88 @@
1/* dso_null.c */
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/* This "NULL" method is provided as the fallback for systems that have
60 * no appropriate support for "shared-libraries". */
61
62#include <stdio.h>
63#include "cryptlib.h"
64#include <openssl/dso.h>
65
66static DSO_METHOD dso_meth_null = {
67 "NULL shared library method",
68 NULL, /* load */
69 NULL, /* unload */
70 NULL, /* bind_var */
71 NULL, /* bind_func */
72/* For now, "unbind" doesn't exist */
73#if 0
74 NULL, /* unbind_var */
75 NULL, /* unbind_func */
76#endif
77 NULL, /* ctrl */
78 NULL, /* dso_name_converter */
79 NULL, /* dso_merger */
80 NULL, /* init */
81 NULL /* finish */
82 };
83
84DSO_METHOD *DSO_METHOD_null(void)
85 {
86 return(&dso_meth_null);
87 }
88
diff --git a/src/lib/libcrypto/dso/dso_openssl.c b/src/lib/libcrypto/dso/dso_openssl.c
new file mode 100644
index 0000000000..a4395ebffe
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_openssl.c
@@ -0,0 +1,81 @@
1/* dso_openssl.c */
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 "cryptlib.h"
61#include <openssl/dso.h>
62
63/* We just pinch the method from an appropriate "default" method. */
64
65DSO_METHOD *DSO_METHOD_openssl(void)
66 {
67#ifdef DEF_DSO_METHOD
68 return(DEF_DSO_METHOD());
69#elif defined(DSO_DLFCN)
70 return(DSO_METHOD_dlfcn());
71#elif defined(DSO_DL)
72 return(DSO_METHOD_dl());
73#elif defined(DSO_WIN32)
74 return(DSO_METHOD_win32());
75#elif defined(DSO_VMS)
76 return(DSO_METHOD_vms());
77#else
78 return(DSO_METHOD_null());
79#endif
80 }
81
diff --git a/src/lib/libcrypto/dso/dso_vms.c b/src/lib/libcrypto/dso/dso_vms.c
new file mode 100644
index 0000000000..2c434ee8a6
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_vms.c
@@ -0,0 +1,504 @@
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#endif
72
73#ifndef OPENSSL_SYS_VMS
74DSO_METHOD *DSO_METHOD_vms(void)
75 {
76 return NULL;
77 }
78#else
79#pragma message disable DOLLARID
80
81static int vms_load(DSO *dso);
82static int vms_unload(DSO *dso);
83static void *vms_bind_var(DSO *dso, const char *symname);
84static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname);
85#if 0
86static int vms_unbind_var(DSO *dso, char *symname, void *symptr);
87static int vms_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
88static int vms_init(DSO *dso);
89static int vms_finish(DSO *dso);
90static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg);
91#endif
92static char *vms_name_converter(DSO *dso, const char *filename);
93static char *vms_merger(DSO *dso, const char *filespec1,
94 const char *filespec2);
95
96static DSO_METHOD dso_meth_vms = {
97 "OpenSSL 'VMS' shared library method",
98 vms_load,
99 NULL, /* unload */
100 vms_bind_var,
101 vms_bind_func,
102/* For now, "unbind" doesn't exist */
103#if 0
104 NULL, /* unbind_var */
105 NULL, /* unbind_func */
106#endif
107 NULL, /* ctrl */
108 vms_name_converter,
109 vms_merger,
110 NULL, /* init */
111 NULL /* finish */
112 };
113
114/* On VMS, the only "handle" is the file name. LIB$FIND_IMAGE_SYMBOL depends
115 * on the reference to the file name being the same for all calls regarding
116 * one shared image, so we'll just store it in an instance of the following
117 * structure and put a pointer to that instance in the meth_data stack.
118 */
119typedef struct dso_internal_st
120 {
121 /* This should contain the name only, no directory,
122 * no extension, nothing but a name. */
123 struct dsc$descriptor_s filename_dsc;
124 char filename[FILENAME_MAX+1];
125 /* This contains whatever is not in filename, if needed.
126 * Normally not defined. */
127 struct dsc$descriptor_s imagename_dsc;
128 char imagename[FILENAME_MAX+1];
129 } DSO_VMS_INTERNAL;
130
131
132DSO_METHOD *DSO_METHOD_vms(void)
133 {
134 return(&dso_meth_vms);
135 }
136
137static int vms_load(DSO *dso)
138 {
139 void *ptr = NULL;
140 /* See applicable comments in dso_dl.c */
141 char *filename = DSO_convert_filename(dso, NULL);
142 DSO_VMS_INTERNAL *p;
143 const char *sp1, *sp2; /* Search result */
144
145 if(filename == NULL)
146 {
147 DSOerr(DSO_F_VMS_LOAD,DSO_R_NO_FILENAME);
148 goto err;
149 }
150
151 /* A file specification may look like this:
152 *
153 * node::dev:[dir-spec]name.type;ver
154 *
155 * or (for compatibility with TOPS-20):
156 *
157 * node::dev:<dir-spec>name.type;ver
158 *
159 * and the dir-spec uses '.' as separator. Also, a dir-spec
160 * may consist of several parts, with mixed use of [] and <>:
161 *
162 * [dir1.]<dir2>
163 *
164 * We need to split the file specification into the name and
165 * the rest (both before and after the name itself).
166 */
167 /* Start with trying to find the end of a dir-spec, and save the
168 position of the byte after in sp1 */
169 sp1 = strrchr(filename, ']');
170 sp2 = strrchr(filename, '>');
171 if (sp1 == NULL) sp1 = sp2;
172 if (sp2 != NULL && sp2 > sp1) sp1 = sp2;
173 if (sp1 == NULL) sp1 = strrchr(filename, ':');
174 if (sp1 == NULL)
175 sp1 = filename;
176 else
177 sp1++; /* The byte after the found character */
178 /* Now, let's see if there's a type, and save the position in sp2 */
179 sp2 = strchr(sp1, '.');
180 /* If we found it, that's where we'll cut. Otherwise, look for a
181 version number and save the position in sp2 */
182 if (sp2 == NULL) sp2 = strchr(sp1, ';');
183 /* If there was still nothing to find, set sp2 to point at the end of
184 the string */
185 if (sp2 == NULL) sp2 = sp1 + strlen(sp1);
186
187 /* Check that we won't get buffer overflows */
188 if (sp2 - sp1 > FILENAME_MAX
189 || (sp1 - filename) + strlen(sp2) > FILENAME_MAX)
190 {
191 DSOerr(DSO_F_VMS_LOAD,DSO_R_FILENAME_TOO_BIG);
192 goto err;
193 }
194
195 p = (DSO_VMS_INTERNAL *)OPENSSL_malloc(sizeof(DSO_VMS_INTERNAL));
196 if(p == NULL)
197 {
198 DSOerr(DSO_F_VMS_LOAD,ERR_R_MALLOC_FAILURE);
199 goto err;
200 }
201
202 strncpy(p->filename, sp1, sp2-sp1);
203 p->filename[sp2-sp1] = '\0';
204
205 strncpy(p->imagename, filename, sp1-filename);
206 p->imagename[sp1-filename] = '\0';
207 strcat(p->imagename, sp2);
208
209 p->filename_dsc.dsc$w_length = strlen(p->filename);
210 p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
211 p->filename_dsc.dsc$b_class = DSC$K_CLASS_S;
212 p->filename_dsc.dsc$a_pointer = p->filename;
213 p->imagename_dsc.dsc$w_length = strlen(p->imagename);
214 p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
215 p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S;
216 p->imagename_dsc.dsc$a_pointer = p->imagename;
217
218 if(!sk_push(dso->meth_data, (char *)p))
219 {
220 DSOerr(DSO_F_VMS_LOAD,DSO_R_STACK_ERROR);
221 goto err;
222 }
223
224 /* Success (for now, we lie. We actually do not know...) */
225 dso->loaded_filename = filename;
226 return(1);
227err:
228 /* Cleanup! */
229 if(p != NULL)
230 OPENSSL_free(p);
231 if(filename != NULL)
232 OPENSSL_free(filename);
233 return(0);
234 }
235
236/* Note that this doesn't actually unload the shared image, as there is no
237 * such thing in VMS. Next time it get loaded again, a new copy will
238 * actually be loaded.
239 */
240static int vms_unload(DSO *dso)
241 {
242 DSO_VMS_INTERNAL *p;
243 if(dso == NULL)
244 {
245 DSOerr(DSO_F_VMS_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
246 return(0);
247 }
248 if(sk_num(dso->meth_data) < 1)
249 return(1);
250 p = (DSO_VMS_INTERNAL *)sk_pop(dso->meth_data);
251 if(p == NULL)
252 {
253 DSOerr(DSO_F_VMS_UNLOAD,DSO_R_NULL_HANDLE);
254 return(0);
255 }
256 /* Cleanup */
257 OPENSSL_free(p);
258 return(1);
259 }
260
261/* We must do this in a separate function because of the way the exception
262 handler works (it makes this function return */
263static int do_find_symbol(DSO_VMS_INTERNAL *ptr,
264 struct dsc$descriptor_s *symname_dsc, void **sym,
265 unsigned long flags)
266 {
267 /* Make sure that signals are caught and returned instead of
268 aborting the program. The exception handler gets unestablished
269 automatically on return from this function. */
270 lib$establish(lib$sig_to_ret);
271
272 if(ptr->imagename_dsc.dsc$w_length)
273 return lib$find_image_symbol(&ptr->filename_dsc,
274 symname_dsc, sym,
275 &ptr->imagename_dsc, flags);
276 else
277 return lib$find_image_symbol(&ptr->filename_dsc,
278 symname_dsc, sym,
279 0, flags);
280 }
281
282void vms_bind_sym(DSO *dso, const char *symname, void **sym)
283 {
284 DSO_VMS_INTERNAL *ptr;
285 int status;
286#if 0
287 int flags = (1<<4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't
288 defined in VMS older than 7.0 or so */
289#else
290 int flags = 0;
291#endif
292 struct dsc$descriptor_s symname_dsc;
293 *sym = NULL;
294
295 symname_dsc.dsc$w_length = strlen(symname);
296 symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
297 symname_dsc.dsc$b_class = DSC$K_CLASS_S;
298 symname_dsc.dsc$a_pointer = (char *)symname; /* The cast is needed */
299
300 if((dso == NULL) || (symname == NULL))
301 {
302 DSOerr(DSO_F_VMS_BIND_SYM,ERR_R_PASSED_NULL_PARAMETER);
303 return;
304 }
305 if(sk_num(dso->meth_data) < 1)
306 {
307 DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_STACK_ERROR);
308 return;
309 }
310 ptr = (DSO_VMS_INTERNAL *)sk_value(dso->meth_data,
311 sk_num(dso->meth_data) - 1);
312 if(ptr == NULL)
313 {
314 DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_NULL_HANDLE);
315 return;
316 }
317
318 if(dso->flags & DSO_FLAG_UPCASE_SYMBOL) flags = 0;
319
320 status = do_find_symbol(ptr, &symname_dsc, sym, flags);
321
322 if(!$VMS_STATUS_SUCCESS(status))
323 {
324 unsigned short length;
325 char errstring[257];
326 struct dsc$descriptor_s errstring_dsc;
327
328 errstring_dsc.dsc$w_length = sizeof(errstring);
329 errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
330 errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
331 errstring_dsc.dsc$a_pointer = errstring;
332
333 *sym = NULL;
334
335 status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
336
337 if (!$VMS_STATUS_SUCCESS(status))
338 lib$signal(status); /* This is really bad. Abort! */
339 else
340 {
341 errstring[length] = '\0';
342
343 DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_SYM_FAILURE);
344 if (ptr->imagename_dsc.dsc$w_length)
345 ERR_add_error_data(9,
346 "Symbol ", symname,
347 " in ", ptr->filename,
348 " (", ptr->imagename, ")",
349 ": ", errstring);
350 else
351 ERR_add_error_data(6,
352 "Symbol ", symname,
353 " in ", ptr->filename,
354 ": ", errstring);
355 }
356 return;
357 }
358 return;
359 }
360
361static void *vms_bind_var(DSO *dso, const char *symname)
362 {
363 void *sym = 0;
364 vms_bind_sym(dso, symname, &sym);
365 return sym;
366 }
367
368static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname)
369 {
370 DSO_FUNC_TYPE sym = 0;
371 vms_bind_sym(dso, symname, (void **)&sym);
372 return sym;
373 }
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
496static char *vms_name_converter(DSO *dso, const char *filename)
497 {
498 int len = strlen(filename);
499 char *not_translated = OPENSSL_malloc(len+1);
500 strcpy(not_translated,filename);
501 return(not_translated);
502 }
503
504#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..fd3dd6a7fe
--- /dev/null
+++ b/src/lib/libcrypto/dso/dso_win32.c
@@ -0,0 +1,660 @@
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) 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 }
108#endif
109
110/* Part of the hack in "win32_load" ... */
111#define DSO_MAX_TRANSLATED_SIZE 256
112
113static int win32_load(DSO *dso);
114static int win32_unload(DSO *dso);
115static void *win32_bind_var(DSO *dso, const char *symname);
116static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
117#if 0
118static int win32_unbind_var(DSO *dso, char *symname, void *symptr);
119static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
120static int win32_init(DSO *dso);
121static int win32_finish(DSO *dso);
122static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
123#endif
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);
129
130static DSO_METHOD dso_meth_win32 = {
131 "OpenSSL 'win32' shared library method",
132 win32_load,
133 win32_unload,
134 win32_bind_var,
135 win32_bind_func,
136/* For now, "unbind" doesn't exist */
137#if 0
138 NULL, /* unbind_var */
139 NULL, /* unbind_func */
140#endif
141 NULL, /* ctrl */
142 win32_name_converter,
143 win32_merger,
144 NULL, /* init */
145 NULL /* finish */
146 };
147
148DSO_METHOD *DSO_METHOD_win32(void)
149 {
150 return(&dso_meth_win32);
151 }
152
153/* For this DSO_METHOD, our meth_data STACK will contain;
154 * (i) a pointer to the handle (HINSTANCE) returned from
155 * LoadLibrary(), and copied.
156 */
157
158static int win32_load(DSO *dso)
159 {
160 HINSTANCE h = NULL, *p = NULL;
161 /* See applicable comments from dso_dl.c */
162 char *filename = DSO_convert_filename(dso, NULL);
163
164 if(filename == NULL)
165 {
166 DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME);
167 goto err;
168 }
169 h = LoadLibraryA(filename);
170 if(h == NULL)
171 {
172 DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
173 ERR_add_error_data(3, "filename(", filename, ")");
174 goto err;
175 }
176 p = (HINSTANCE *)OPENSSL_malloc(sizeof(HINSTANCE));
177 if(p == NULL)
178 {
179 DSOerr(DSO_F_WIN32_LOAD,ERR_R_MALLOC_FAILURE);
180 goto err;
181 }
182 *p = h;
183 if(!sk_push(dso->meth_data, (char *)p))
184 {
185 DSOerr(DSO_F_WIN32_LOAD,DSO_R_STACK_ERROR);
186 goto err;
187 }
188 /* Success */
189 dso->loaded_filename = filename;
190 return(1);
191err:
192 /* Cleanup !*/
193 if(filename != NULL)
194 OPENSSL_free(filename);
195 if(p != NULL)
196 OPENSSL_free(p);
197 if(h != NULL)
198 FreeLibrary(h);
199 return(0);
200 }
201
202static int win32_unload(DSO *dso)
203 {
204 HINSTANCE *p;
205 if(dso == NULL)
206 {
207 DSOerr(DSO_F_WIN32_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
208 return(0);
209 }
210 if(sk_num(dso->meth_data) < 1)
211 return(1);
212 p = (HINSTANCE *)sk_pop(dso->meth_data);
213 if(p == NULL)
214 {
215 DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_NULL_HANDLE);
216 return(0);
217 }
218 if(!FreeLibrary(*p))
219 {
220 DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_UNLOAD_FAILED);
221 /* We should push the value back onto the stack in
222 * case of a retry. */
223 sk_push(dso->meth_data, (char *)p);
224 return(0);
225 }
226 /* Cleanup */
227 OPENSSL_free(p);
228 return(1);
229 }
230
231/* Using GetProcAddress for variables? TODO: Check this out in
232 * the Win32 API docs, there's probably a variant for variables. */
233static void *win32_bind_var(DSO *dso, const char *symname)
234 {
235 HINSTANCE *ptr;
236 void *sym;
237
238 if((dso == NULL) || (symname == NULL))
239 {
240 DSOerr(DSO_F_WIN32_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
241 return(NULL);
242 }
243 if(sk_num(dso->meth_data) < 1)
244 {
245 DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_STACK_ERROR);
246 return(NULL);
247 }
248 ptr = (HINSTANCE *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
249 if(ptr == NULL)
250 {
251 DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_NULL_HANDLE);
252 return(NULL);
253 }
254 sym = GetProcAddress(*ptr, symname);
255 if(sym == NULL)
256 {
257 DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_SYM_FAILURE);
258 ERR_add_error_data(3, "symname(", symname, ")");
259 return(NULL);
260 }
261 return(sym);
262 }
263
264static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
265 {
266 HINSTANCE *ptr;
267 void *sym;
268
269 if((dso == NULL) || (symname == NULL))
270 {
271 DSOerr(DSO_F_WIN32_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
272 return(NULL);
273 }
274 if(sk_num(dso->meth_data) < 1)
275 {
276 DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_STACK_ERROR);
277 return(NULL);
278 }
279 ptr = (HINSTANCE *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
280 if(ptr == NULL)
281 {
282 DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_NULL_HANDLE);
283 return(NULL);
284 }
285 sym = GetProcAddress(*ptr, symname);
286 if(sym == NULL)
287 {
288 DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_SYM_FAILURE);
289 ERR_add_error_data(3, "symname(", symname, ")");
290 return(NULL);
291 }
292 return((DSO_FUNC_TYPE)sym);
293 }
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
619static char *win32_name_converter(DSO *dso, const char *filename)
620 {
621 char *translated;
622 int len, transform;
623
624 len = strlen(filename);
625 transform = ((strstr(filename, "/") == NULL) &&
626 (strstr(filename, "\\") == NULL) &&
627 (strstr(filename, ":") == NULL));
628 if(transform)
629 /* We will convert this to "%s.dll" */
630 translated = OPENSSL_malloc(len + 5);
631 else
632 /* We will simply duplicate filename */
633 translated = OPENSSL_malloc(len + 1);
634 if(translated == NULL)
635 {
636 DSOerr(DSO_F_WIN32_NAME_CONVERTER,
637 DSO_R_NAME_TRANSLATION_FAILED);
638 return(NULL);
639 }
640 if(transform)
641 sprintf(translated, "%s.dll", filename);
642 else
643 sprintf(translated, "%s", filename);
644 return(translated);
645 }
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
660#endif /* OPENSSL_SYS_WIN32 */