diff options
author | Aleksey Sanin <aleksey@src.gnome.org> | 2003-09-09 19:59:02 +0000 |
---|---|---|
committer | Aleksey Sanin <aleksey@src.gnome.org> | 2003-09-09 19:59:02 +0000 |
commit | 358548836a1ece218ecbcf13ab73ddbc443e3137 (patch) | |
tree | b8956981a56a2e1a5f26f7924deb3263b0065b47 | |
parent | cce1030351bc78420ed485aeec76d6ab8b22965c (diff) | |
download | xmlsec1-358548836a1ece218ecbcf13ab73ddbc443e3137.tar.gz xmlsec1-358548836a1ece218ecbcf13ab73ddbc443e3137.tar.bz2 xmlsec1-358548836a1ece218ecbcf13ab73ddbc443e3137.zip |
implemented loading xmlsec-crypto libraries as plugins change build to
* Makefile.am apps/* configure.in include/* src/* tests/*: implemented
loading xmlsec-crypto libraries as plugins
* win32/: change build to allow building of more than one
xmlsec-crypto library
62 files changed, 11844 insertions, 958 deletions
@@ -1,3 +1,10 @@ +Tue Sep 9 12:52:00 2003 Aleksey Sanin <aleksey@aleksey.com> + + * Makefile.am apps/* configure.in include/* src/* tests/*: implemented + loading xmlsec-crypto libraries as plugins + * win32/: change build to allow building of more than one + xmlsec-crypto library + Sun 24 Aug 2003 05:20:14 PM PDT Aleksey Sanin <aleksey@aleksey.com> * docs/faq.html: upgraded licenses FAQ section to include diff --git a/Makefile.am b/Makefile.am index 44ec23c7..231db8c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -44,19 +44,47 @@ EXTRA_CLEAN = \ examples \ $(NULL) +if XMLSEC_APPS_NO_CRYPTO_DYNAMIC_LOADING +PRECHECK_COMMANDS = \ + ABS_BUILDDIR=`pwd` && cd $(top_srcdir) \ + $(NULL) +CHECK_CRYPTO_LIST = \ + "default" \ + $(NULL) +else +CRYPTO_FOLDERS=$(patsubst %,$(top_builddir)/src/%/.libs:,$(XMLSEC_CRYPTO_LIST)) +PRECHECK_COMMANDS= \ + ABS_BUILDDIR=`pwd` && cd $(top_srcdir) && \ + export LD_LIBRARY_PATH="$(CRYPTO_FOLDERS)$$LD_LIBRARY_PATH" \ + $(NULL) +CHECK_CRYPTO_LIST = \ + $(XMLSEC_CRYPTO_LIST) \ + $(NULL) +endif + xmlsec1.pc: xmlsec1-@XMLSEC_CRYPTO@.pc @(rm -f xmlsec1.pc && $(LN_S) xmlsec1-@XMLSEC_CRYPTO@.pc xmlsec1.pc) docs: docs-man - @(cd docs; $(MAKE) docs) + @(cd docs && $(MAKE) docs) docs-clean: - @(cd docs; $(MAKE) clean) + @(cd docs && $(MAKE) clean) docs-man: - @(cd man;$(MAKE) docs) + @(cd man && $(MAKE) docs) + +check: check-all check-info + +check-all: $(TEST_APP) reset-nss-db + @($(PRECHECK_COMMANDS) && \ + for i in $(CHECK_CRYPTO_LIST) ; do \ + echo "=================== Checking xmlsec-$$i =================================" && \ + $(SHELL) ./tests/testKeys.sh $$i ./tests $$ABS_BUILDDIR/$(TEST_APP) der && \ + $(SHELL) ./tests/testDSig.sh $$i ./tests $$ABS_BUILDDIR/$(top_builddir)/$(TEST_APP) der && \ + $(SHELL) ./tests/testEnc.sh $$i ./tests $$ABS_BUILDDIR/$(TEST_APP) der ; \ + done; ) -check: check-info check-km check-dsig check-enc check-info: @echo "-------------------------- ATTENTION -----------------------------------" @@ -69,25 +97,25 @@ check-info: @echo "-------------------------- ATTENTION -----------------------------------" reset-nss-db: - @(ABS_BUILDDIR=`pwd`; cd $(top_srcdir);\ + @(ABS_BUILDDIR=`pwd` && cd $(top_srcdir) && \ if [ "z$(DEFAULT_CRYPTO)" = "znss" ] ; \ then \ - echo "Removing old nss db and replacing with a new one"; \ - rm -rf ./tests/cert*.db ./tests/key*.db ./tests/secmod*.db; \ + echo "Removing old nss db and replacing with a new one" && \ + rm -rf ./tests/cert*.db ./tests/key*.db ./tests/secmod*.db && \ cp ./tests/nssdb/*.db ./tests; \ fi) check-km: $(TEST_APP) reset-nss-db - @(ABS_BUILDDIR=`pwd`; cd $(top_srcdir); \ - $(SHELL) ./tests/testKeys.sh ./tests $$ABS_BUILDDIR/$(TEST_APP) der) + @($(PRECHECK_COMMANDS) && \ + $(SHELL) ./tests/testKeys.sh default ./tests $$ABS_BUILDDIR/$(TEST_APP) der) check-dsig: $(TEST_APP) reset-nss-db - @(ABS_BUILDDIR=`pwd`; cd $(top_srcdir); \ - $(SHELL) ./tests/testDSig.sh ./tests $$ABS_BUILDDIR/$(top_builddir)/$(TEST_APP) der) + @($(PRECHECK_COMMANDS) && \ + $(SHELL) ./tests/testDSig.sh default ./tests $$ABS_BUILDDIR/$(top_builddir)/$(TEST_APP) der) check-enc: $(TEST_APP) reset-nss-db - @(ABS_BUILDDIR="`pwd`"; cd $(top_srcdir); \ - $(SHELL) ./tests/testEnc.sh ./tests $$ABS_BUILDDIR/$(TEST_APP) der) + @($(PRECHECK_COMMANDS) && \ + $(SHELL) ./tests/testEnc.sh default ./tests $$ABS_BUILDDIR/$(TEST_APP) der) memcheck-res: @grep -i lost /tmp/*.log | sed 's/==.*== *//' | sort -u @@ -95,10 +123,10 @@ memcheck-res: @grep -i 'in use' /tmp/*.log | sed 's/==.*== *//' | sort -u memcheck: $(TEST_APP) - @(export DEBUG_MEMORY=1;$(MAKE) check;$(MAKE) memcheck-res) + @(export DEBUG_MEMORY=1 && $(MAKE) check && $(MAKE) memcheck-res) perfcheck: $(TEST_APP) - @(export PERF_TEST=10;$(MAKE) check) + @(export PERF_TEST=10 && $(MAKE) check) dist-hook: @(rm -rf `find $(distdir) -name CVS`) @@ -107,7 +135,7 @@ cleantar: @(rm -f xmlsec*.tar.gz COPYING.LIB) rpm: cleantar - @(unset CDPATH ; $(MAKE) dist && rpmbuild -ta $(distdir).tar.gz) + @(unset CDPATH && $(MAKE) dist && rpmbuild -ta $(distdir).tar.gz) tag-release: @cvs tag -F xmlsec-$(SAFE_VERSION) > /dev/null @@ -0,0 +1,4 @@ +- Fix the shared library filename format in dl.c (extension at least) +- Update docs +- Write tutorial about dl + diff --git a/apps/Makefile.am b/apps/Makefile.am index 960dac0d..7fc2397b 100644 --- a/apps/Makefile.am +++ b/apps/Makefile.am @@ -2,35 +2,81 @@ NULL = bin_PROGRAMS = xmlsec1 -INCLUDES = \ - -DXMLSEC_CRYPTO=\"@XMLSEC_CRYPTO@\" \ - -I$(top_srcdir)/include \ - $(XMLSEC_DEFINES) \ - $(XMLSEC_CRYPTO_CFLAGS) \ - $(LIBXSLT_CFLAGS) \ - $(LIBXML_CFLAGS) \ - $(NULL) +# check if we use dynamic loading for xmlsec-crypto or not +if XMLSEC_APPS_NO_CRYPTO_DYNAMIC_LOADING + +CRYPTO_DEPS = \ + $(top_builddir)/src/$(XMLSEC_CRYPTO)/lib$(XMLSEC_CRYPTO_LIB).la \ + $(top_builddir)/src/libxmlsec1.la \ + $(NULL) + +CRYPTO_INCLUDES = \ + $(XMLSEC_CRYPTO_CFLAGS) \ + $(NULL) + +CRYPTO_LD_FLAGS = \ + $(NULL) + +CRYPTO_LD_ADD = \ + $(CRYPTO_DEPS) \ + $(XMLSEC_CRYPTO_LIBS) \ + $(NULL) + +else + +CRYPTO_DEPS = \ + $(top_builddir)/src/libxmlsec1.la \ + $(NULL) + +CRYPTO_INCLUDES = \ + -DXMLSEC_CRYPTO_DYNAMIC_LOADING=1 + $(NULL) + +CRYPTO_LD_FLAGS = \ + $(NULL) -DEPS = \ - $(top_builddir)/src/$(XMLSEC_CRYPTO)/lib$(XMLSEC_CRYPTO_LIB).la \ - $(top_builddir)/src/libxmlsec1.la \ - $(NULL) +CRYPTO_LD_ADD = \ + $(CRYPTO_DEPS) \ + $(NULL) + +endif + + +INCLUDES = \ + -DXMLSEC_CRYPTO=\"@XMLSEC_CRYPTO@\" \ + -DPACKAGE=\"@PACKAGE@\" \ + -I$(top_srcdir)/include \ + $(XMLSEC_DEFINES) \ + $(XMLSEC_APP_DEFINES) \ + $(CRYPTO_INCLUDES) \ + $(LIBXSLT_CFLAGS) \ + $(LIBXML_CFLAGS) \ + $(XMLSEC_DL_INCLUDES) \ + $(NULL) # xmlsec command line utility xmlsec1_SOURCES = \ - xmlsec.c \ - crypto.c crypto.h \ - cmdline.c cmdline.h \ - $(NULL) + xmlsec.c \ + crypto.c crypto.h \ + cmdline.c cmdline.h \ + $(NULL) xmlsec1_LDFLAGS = \ - @XMLSEC_STATIC_BINARIES@ \ - $(NULL) + $(CRYPTO_LD_FLAGS) \ + @XMLSEC_STATIC_BINARIES@ \ + $(NULL) xmlsec1_LDADD = \ - $(DEPS) \ - $(LIBXSLT_LIBS) \ - $(LIBXML_LIBS) \ - $(XMLSEC_CRYPTO_LIBS) \ - $(NULL) + $(CRYPTO_LD_ADD) \ + $(LIBXSLT_LIBS) \ + $(LIBXML_LIBS) \ + $(XMLSEC_DL_LIBS) \ + $(NULL) + +xmlsec1_DEPENDENCIES = \ + $(CRYPTO_DEPS) \ + $(NULL) + + + diff --git a/apps/cmdline.c b/apps/cmdline.c index c44b3eda..5f7f6179 100644 --- a/apps/cmdline.c +++ b/apps/cmdline.c @@ -252,7 +252,7 @@ xmlSecAppCmdLineParamRead(xmlSecAppCmdLineParamPtr param, const char** argv, int ++value->paramNameValue; } } - + switch(param->type) { case xmlSecAppCmdLineParamTypeFlag: /* do nothing */ diff --git a/apps/crypto.c b/apps/crypto.c index ca260241..5e3d5ca3 100644 --- a/apps/crypto.c +++ b/apps/crypto.c @@ -112,7 +112,8 @@ xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(xmlSecKeysMngrPtr mngr, xmlSecAssert2(files != NULL, -1); /* first is the key file */ - key = xmlSecCryptoAppKeyLoad(files, format, pwd, NULL, NULL); + key = xmlSecCryptoAppKeyLoad(files, format, pwd, + xmlSecCryptoAppGetDefaultPwdCallback(), (void*)files); if(key == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, @@ -181,32 +182,14 @@ xmlSecAppCryptoSimpleKeysMngrKeyAndCertsLoad(xmlSecKeysMngrPtr mngr, int xmlSecAppCryptoSimpleKeysMngrPkcs12KeyLoad(xmlSecKeysMngrPtr mngr, const char *filename, const char* pwd, const char *name) { xmlSecKeyPtr key; - char buf[1024] = ""; - char prompt[2048]; int ret; xmlSecAssert2(mngr != NULL, -1); xmlSecAssert2(filename != NULL, -1); #ifndef XMLSEC_NO_X509 -#ifdef XMLSEC_CRYPTO_OPENSSL - if(pwd == NULL) { - snprintf(prompt, sizeof(prompt), "Password for pkcs12 file \"%s\": ", filename); - ret = EVP_read_pw_string(buf, sizeof(buf), prompt, 0); - if(ret != 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "EVP_read_pw_string", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - pwd = buf; - } -#endif /* XMLSEC_CRYPTO_OPENSSL */ - - key = xmlSecCryptoAppKeyLoad(filename, xmlSecKeyDataFormatPkcs12, - pwd, NULL, NULL); + key = xmlSecCryptoAppKeyLoad(filename, xmlSecKeyDataFormatPkcs12, pwd, + xmlSecCryptoAppGetDefaultPwdCallback(), (void*)filename); if(key == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, @@ -214,10 +197,8 @@ xmlSecAppCryptoSimpleKeysMngrPkcs12KeyLoad(xmlSecKeysMngrPtr mngr, const char *f XMLSEC_ERRORS_R_XMLSEC_FAILED, "filename=%s", xmlSecErrorsSafeString(filename)); - memset(buf, 0, sizeof(buf)); return(-1); } - memset(buf, 0, sizeof(buf)); if(name != NULL) { ret = xmlSecKeySetName(key, BAD_CAST name); diff --git a/apps/xmlsec.c b/apps/xmlsec.c index 51409ec1..d1b19b17 100644 --- a/apps/xmlsec.c +++ b/apps/xmlsec.c @@ -156,17 +156,32 @@ static xmlSecAppCmdLineParam helpParam = { NULL }; +#if !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) +static xmlSecAppCmdLineParam cryptoParam = { + xmlSecAppCmdLineTopicGeneral, + "--crypto", + NULL, + "--crypto <name>" + "\n\tthe name of the crypto engine to use (if not specified, the default" + "\n\tcrypto engine is used)", + xmlSecAppCmdLineParamTypeString, + xmlSecAppCmdLineParamFlagNone, + NULL +}; +#endif /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + static xmlSecAppCmdLineParam cryptoConfigParam = { xmlSecAppCmdLineTopicGeneral, "--crypto-config", NULL, - "--crypto-config" + "--crypto-config <path>" "\n\tpath to crypto engine configuration", xmlSecAppCmdLineParamTypeString, xmlSecAppCmdLineParamFlagNone, NULL }; + static xmlSecAppCmdLineParam repeatParam = { xmlSecAppCmdLineTopicGeneral, "--repeat", @@ -195,7 +210,7 @@ static xmlSecAppCmdLineParam printCryptoErrorMsgsParam = { "--print-crypto-error-msgs", NULL, "--print-crypto-error-msgs" - "\n\tprint openssl errors stack at the end", + "\n\tprint errors stack at the end", xmlSecAppCmdLineParamTypeFlag, xmlSecAppCmdLineParamFlagNone, NULL @@ -740,6 +755,9 @@ static xmlSecAppCmdLineParamPtr parameters[] = { #endif /* XMLSEC_NO_X509 */ /* General configuration params */ +#if !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) + &cryptoParam, +#endif /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ &cryptoConfigParam, &repeatParam, &disableErrorMsgsParam, @@ -832,6 +850,8 @@ xmlSecKeysMngrPtr gKeysMngr = NULL; int repeats = 1; int print_debug = 0; clock_t total_time = 0; +const char* xmlsec_crypto = XMLSEC_CRYPTO; +const char* tmp = NULL; int main(int argc, const char **argv) { xmlSecAppCmdLineParamTopic cmdLineTopics; @@ -856,7 +876,7 @@ int main(int argc, const char **argv) { xmlSecAppPrintHelp(subCommand, cmdLineTopics); goto success; } else if(command == xmlSecAppCommandVersion) { - fprintf(stdout, "%s %s (%s)\n", XMLSEC_PACKAGE, XMLSEC_VERSION, XMLSEC_CRYPTO); + fprintf(stdout, "%s %s (%s)\n", XMLSEC_PACKAGE, XMLSEC_VERSION, xmlsec_crypto); goto success; } @@ -894,6 +914,13 @@ int main(int argc, const char **argv) { } /* now init the xmlsec and all other libs */ +#if !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) + tmp = xmlSecAppCmdLineParamGetString(&cryptoParam); + if((tmp != NULL) && (strcmp(tmp, "default") != 0)) { + xmlsec_crypto = tmp; + } +#endif /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + if(xmlSecAppInit() < 0) { fprintf(stderr, "Error: initialization failed\n"); xmlSecAppPrintUsage(); @@ -2190,6 +2217,13 @@ xmlSecAppInit(void) { return(-1); } +#if !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) + if(xmlSecCryptoDLLoadLibrary(BAD_CAST xmlsec_crypto) < 0) { + fprintf(stderr, "Error: unable to load xmlsec-%s library. Check shared libraries path or use \"--crypto\" option to specify different crypto engine.\n", xmlsec_crypto); + return(-1); + } +#endif /* !defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + /* Init Crypto */ if(xmlSecAppCryptoInit(xmlSecAppCmdLineParamGetString(&cryptoConfigParam)) < 0) { fprintf(stderr, "Error: xmlsec crypto intialization failed.\n"); diff --git a/config.h.in b/config.h.in index 8bb77c0f..179f2591 100644 --- a/config.h.in +++ b/config.h.in @@ -3,6 +3,30 @@ /* Define to 1 if you have the <ansidecl.h> header file. */ #undef HAVE_ANSIDECL_H +/* Define to 1 if you have the `argz_append' function. */ +#undef HAVE_ARGZ_APPEND + +/* Define to 1 if you have the `argz_create_sep' function. */ +#undef HAVE_ARGZ_CREATE_SEP + +/* Define to 1 if you have the <argz.h> header file. */ +#undef HAVE_ARGZ_H + +/* Define to 1 if you have the `argz_insert' function. */ +#undef HAVE_ARGZ_INSERT + +/* Define to 1 if you have the `argz_next' function. */ +#undef HAVE_ARGZ_NEXT + +/* Define to 1 if you have the `argz_stringify' function. */ +#undef HAVE_ARGZ_STRINGIFY + +/* Define to 1 if you have the <assert.h> header file. */ +#undef HAVE_ASSERT_H + +/* Define to 1 if you have the `bcopy' function. */ +#undef HAVE_BCOPY + /* Define to 1 if you have the <ctype.h> header file. */ #undef HAVE_CTYPE_H @@ -10,27 +34,66 @@ */ #undef HAVE_DIRENT_H +/* Define if you have the GNU dld library. */ +#undef HAVE_DLD + +/* Define to 1 if you have the <dld.h> header file. */ +#undef HAVE_DLD_H + +/* Define to 1 if you have the `dlerror' function. */ +#undef HAVE_DLERROR + /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the <dl.h> header file. */ +#undef HAVE_DL_H + /* Define to 1 if you have the <errno.h> header file. */ #undef HAVE_ERRNO_H +/* Define to 1 if the system has the type `error_t'. */ +#undef HAVE_ERROR_T + /* Define to 1 if you have the `fprintf' function. */ #undef HAVE_FPRINTF +/* Define to 1 if you have the `index' function. */ +#undef HAVE_INDEX + /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H +/* Define if you have the libdl library or equivalent. */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the <malloc.h> header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the `memcpy' function. */ +#undef HAVE_MEMCPY + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ #undef HAVE_NDIR_H +/* Define if libtool can extract symbol lists from object files. */ +#undef HAVE_PRELOADED_SYMBOLS + /* Define to 1 if you have the `printf' function. */ #undef HAVE_PRINTF +/* Define to 1 if you have the `rindex' function. */ +#undef HAVE_RINDEX + +/* Define if you have the shl_load function. */ +#undef HAVE_SHL_LOAD + /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF @@ -49,16 +112,28 @@ /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strcmp' function. */ +#undef HAVE_STRCMP + /* Define to 1 if you have the <strings.h> header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + /* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H +/* Define to 1 if you have the <sys/dl.h> header file. */ +#undef HAVE_SYS_DL_H + /* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H @@ -87,6 +162,26 @@ /* Define to 1 if you have the `vsprintf' function. */ #undef HAVE_VSPRINTF +/* Define if the OS needs help to load dependent libraries for dlopen(). */ +#undef LTDL_DLOPEN_DEPLIBS + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LTDL_OBJDIR + +/* Define to the name of the environment variable that determines the dynamic + library search path. */ +#undef LTDL_SHLIBPATH_VAR + +/* Define to the extension used for shared libraries, say, ".so". */ +#undef LTDL_SHLIB_EXT + +/* Define to the system default library search path. */ +#undef LTDL_SYSSEARCHPATH + +/* Define if dlsym() requires a leading underscore in symbol names. */ +#undef NEED_USCORE + /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT @@ -110,3 +205,9 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to a type to use for \`error_t' if it is not otherwise available. */ +#undef error_t diff --git a/configure.in b/configure.in index 270ece71..84db65f8 100644 --- a/configure.in +++ b/configure.in @@ -4,6 +4,7 @@ AC_INIT(src/xmlsec.c) AM_CONFIG_HEADER(config.h) AC_CANONICAL_HOST + XMLSEC_PACKAGE=xmlsec1 XMLSEC_VERSION_MAJOR=1 XMLSEC_VERSION_MINOR=1 @@ -30,10 +31,10 @@ dnl dnl Check the environment dnl AC_PROG_CC +AC_PROG_LIBTOOL AC_PROG_INSTALL AC_ARG_PROGRAM AC_STDC_HEADERS -AM_PROG_LIBTOOL AC_PATH_PROG(RM, rm, /bin/rm) AC_PATH_PROG(MV, mv, /bin/mv) AC_PATH_PROG(TAR, tar, /bin/tar) @@ -54,11 +55,10 @@ AC_CHECK_HEADERS([ansidecl.h]) AC_CHECK_HEADERS([time.h]) AC_CHECK_FUNCS(printf sprintf fprintf snprintf vfprintf vsprintf vsnprintf sscanf timegm) - +AC_LIB_LTDL XMLSEC_DEFINES="" - dnl ========================================================================== dnl Specific setup for Aleksey's development environment: dnl - with xkms support (while in development) @@ -72,7 +72,7 @@ if test "$enable_development" = "yes" -o "${LOGNAME}" = "aleksey" ; then enable_xkms="yes" enable_debuging="yes" enable_pedantic="yes" - enable_static_linking="yes" +# enable_static_linking="yes" AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) @@ -88,7 +88,9 @@ case "${host}" in ;; esac +dnl ========================================================================== dnl Check for __FUNCTION__ or __FUNCTION__ +dnl ========================================================================== AC_MSG_CHECKING(for __FUNCTION__ or __func__) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[char *foo = __FUNCTION__;]])], @@ -235,7 +237,7 @@ OPENSSL_PREFIX="" OPENSSL_CFLAGS="-DXMLSEC_CRYPTO=\\\"openssl\\\" -DXMLSEC_CRYPTO_OPENSSL=1" OPENSSL_LIBS="" OPENSSL_LDADDS="" -OPENSSL_CRYPTO_LIB="xmlsec1-openssl" +OPENSSL_CRYPTO_LIB="$PACKAGE-openssl" AC_MSG_CHECKING(for openssl libraries >= $OPENSSL_MIN_VERSION) AC_ARG_WITH(openssl, [ --with-openssl=[PFX] openssl location]) if test "$with_openssl" = "no" ; then @@ -327,6 +329,7 @@ else AC_MSG_RESULT(no) fi fi +AM_CONDITIONAL(OPENSSL_WITHOUT, test "x$OPENSSL_WITHOUT" = "xyes") AC_SUBST(OPENSSL_WITHOUT) AC_SUBST(OPENSSL_MIN_VERSION) AC_SUBST(OPENSSL_VERSION) @@ -348,7 +351,7 @@ GNUTLS_PREFIX="" GNUTLS_CFLAGS="-DXMLSEC_CRYPTO=\\\"gnutls\\\" -DXMLSEC_CRYPTO_GNUTLS=1" GNUTLS_LIBS="" GNUTLS_LDADDS="" -GNUTLS_CRYPTO_LIB="xmlsec1-gnutls" +GNUTLS_CRYPTO_LIB="$PACKAGE-gnutls" AC_MSG_CHECKING(for gnutls libraries >= $GNUTLS_MIN_VERSION) AC_ARG_WITH(gnutls, [ --with-gnutls=[PFX] gnutls location]) @@ -399,6 +402,7 @@ else AC_MSG_RESULT(no) fi fi +AM_CONDITIONAL(GNUTLS_WITHOUT, test "x$GNUTLS_WITHOUT" = "xyes") AC_SUBST(GNUTLS_WITHOUT) AC_SUBST(GNUTLS_MIN_VERSION) AC_SUBST(GNUTLS_VERSION) @@ -439,7 +443,7 @@ NSS_PREFIX="" NSPR_PREFIX="" NSS_LIBS_LIST="-lnss3 -lsmime3" NSPR_LIBS_LIST="-lnspr4 -lplds4 -lplc4" -NSS_CRYPTO_LIB="xmlsec1-nss" +NSS_CRYPTO_LIB="$PACKAGE-nss" dnl if nss is disabled, bail out early AC_ARG_WITH(nss, [ --with-nss=[PFX] nss location]) @@ -655,7 +659,7 @@ else XMLSEC_CRYPTO_DISABLED_LIST="$XMLSEC_CRYPTO_DISABLED_LIST nss" fi fi - +AM_CONDITIONAL(NSS_WITHOUT, test "x$NSS_WITHOUT" = "xyes") AC_SUBST(NSS_WITHOUT) AC_SUBST(NSS_MIN_VERSION) AC_SUBST(MOZILLA_MIN_VERSION) @@ -847,10 +851,54 @@ fi AC_SUBST(XMLSEC_NO_XKMS) dnl ========================================================================== +dnl check if we need dynamic loading support +dnl ========================================================================== +XMLSEC_DL_INCLUDES="" +XMLSEC_DL_LIBS="" +AC_MSG_CHECKING(for xmlsec-crypto dynamic loading support) +AC_ARG_ENABLE(crypto_dl, [ --enable-crypto-dl enable dynamic loading support for xmlsec-crypto libraries (yes)]) +if test "$enable_crypto_dl" = "no" ; then + XMLSEC_DEFINES="$XMLSEC_DEFINES -DXMLSEC_NO_CRYPTO_DYNAMIC_LOADING=1" + XMLSEC_NO_CRYPTO_DYNAMIC_LOADING="1" + AC_MSG_RESULT(no) +else + XMLSEC_DL_INCLUDES="$INCLTDL" + XMLSEC_DL_LIBS="$LIBLTDL $LIBADD_DL" + XMLSEC_NO_CRYPTO_DYNAMIC_LOADING="0" + AC_MSG_RESULT(yes) +fi +AC_SUBST(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) +AC_SUBST(XMLSEC_DL_INCLUDES) +AC_SUBST(XMLSEC_DL_LIBS) + +dnl ========================================================================== +dnl check if we need dynamic loading in the xmlsec apps +dnl ========================================================================== +AC_MSG_CHECKING(for xmlsec-crypto dynamic loading support in command line tool) +AC_ARG_ENABLE(apps_crypto_dl, [ --apps_enable-crypto-dl enable dynamic loading support for xmlsec-crypto libraries in xmlsec command line tool (yes)]) +if test "z$enable_apps_crypto_dl" = "z" ; then + enable_apps_crypto_dl="$enable_crypto_dl" +fi +if test "z$enable_apps_crypto_dl" = "zno" ; then + XMLSEC_APPS_NO_CRYPTO_DYNAMIC_LOADING="1" + AC_MSG_RESULT(no) +elif test "$enable_crypto_dl" = "no" ; then + AC_MSG_RESULT(no) + AC_MSG_ERROR(xmlsec-crypto libraries dynamic loading support in xmlsec command line tool is requested but no dynamic loading in xmlsec itself is disabled) +else + XMLSEC_APP_DEFINES="$XMLSEC_APP_DEFINES -DXMLSEC_CRYPTO_DYNAMIC_LOADING=1" + XMLSEC_APPS_NO_CRYPTO_DYNAMIC_LOADING="0" + AC_MSG_RESULT(yes) +fi +AM_CONDITIONAL(XMLSEC_APPS_NO_CRYPTO_DYNAMIC_LOADING, + test "x$XMLSEC_APPS_NO_CRYPTO_DYNAMIC_LOADING" = "x1") +AC_SUBST(XMLSEC_APPS_NO_CRYPTO_DYNAMIC_LOADING) + +dnl ========================================================================== dnl See do we need Simple Keys Manager dnl ========================================================================== AC_MSG_CHECKING(for Simple Keys Manager testing) -AC_ARG_ENABLE(skm, [ --enable-skm enable Simple Keys Manager testing(yes)]) +AC_ARG_ENABLE(skm, [ --enable-skm enable Simple Keys Manager testing (yes)]) if test "$enable_skm" = "no" ; then XMLSEC_DEFINES="$XMLSEC_DEFINES -DXMLSEC_NO_SKM_TEST=1" AC_MSG_RESULT(no) @@ -901,7 +949,7 @@ AC_MSG_CHECKING(for pedantic) AC_ARG_ENABLE(pedantic, [ --enable-pedantic enable pedantic compilation flags (no)]) if test "$enable_pedantic" = "yes" ; then dnl CFLAGS="$CFLAGS -pedantic -Wall -ansi -W -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls" - CFLAGS="$CFLAGS -O -pedantic -Wall -ansi -W -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls" + CFLAGS="$CFLAGS -O -pedantic -Wall -ansi -fno-inline -W -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls" AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) @@ -924,8 +972,8 @@ AC_SUBST(XMLSEC_STATIC_BINARIES) dnl ========================================================================== dnl Final steps: xmlsec config dnl ========================================================================== -XMLSEC_CORE_CFLAGS="$XMLSEC_DEFINES -I${includedir}/xmlsec1" -XMLSEC_CORE_LIBS="-lxmlsec1 " +XMLSEC_CORE_CFLAGS="$XMLSEC_DEFINES -I${includedir}/xmlsec1 $XMLSEC_DL_INCLUDES" +XMLSEC_CORE_LIBS="-lxmlsec1 $XMLSEC_DL_LIBS " AC_SUBST(XMLSEC_CORE_CFLAGS) AC_SUBST(XMLSEC_CORE_LIBS) @@ -954,6 +1002,7 @@ AC_SUBST(XMLSEC_CFLAGS) AC_SUBST(XMLSEC_LIBS) AC_SUBST(XMLSEC_DEFINES) +AC_SUBST(XMLSEC_APP_DEFINES) AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(LDFLAGS) @@ -969,7 +1018,7 @@ AC_SUBST(XMLSEC_CRYPTO_LDADDS) XMLSEC_CRYPTO_PC_FILES_LIST="" for i in $XMLSEC_CRYPTO_LIST do - XMLSEC_CRYPTO_PC_FILES_LIST="$XMLSEC_CRYPTO_PC_FILES_LIST xmlsec1-$i.pc" + XMLSEC_CRYPTO_PC_FILES_LIST="$XMLSEC_CRYPTO_PC_FILES_LIST $PACKAGE-$i.pc" done AC_SUBST(XMLSEC_CRYPTO_PC_FILES_LIST) dnl ========================================================================== diff --git a/include/xmlsec/Makefile.am b/include/xmlsec/Makefile.am index 6263081a..4fd55ee8 100644 --- a/include/xmlsec/Makefile.am +++ b/include/xmlsec/Makefile.am @@ -6,9 +6,11 @@ EXTRA_DIST = skeleton $(XMLSEC_CRYPTO_DISABLED_LIST) xmlsecincdir = $(includedir)/xmlsec1/xmlsec xmlsecinc_HEADERS = \ + app.h \ base64.h \ buffer.h \ crypto.h \ + dl.h \ errors.h \ exports.h \ io.h \ @@ -20,6 +22,7 @@ xmlsecinc_HEADERS = \ membuf.h \ nodeset.h \ parser.h \ + private.h \ strings.h \ templates.h \ transforms.h \ diff --git a/include/xmlsec/app.h b/include/xmlsec/app.h new file mode 100644 index 00000000..de99d16c --- /dev/null +++ b/include/xmlsec/app.h @@ -0,0 +1,140 @@ +/** + * XML Security Library (http://www.aleksey.com/xmlsec). + * + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + */ +#ifndef __XMLSEC_APP_H__ +#define __XMLSEC_APP_H__ + +#ifndef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING + +#if !defined(IN_XMLSEC) && !defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) +#error To use dynamic crypto engines loading define XMLSEC_CRYPTO_DYNAMIC_LOADING +#endif /* !defined(IN_XMLSEC) && !defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include <libxml/tree.h> +#include <libxml/xmlIO.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/keysdata.h> +#include <xmlsec/keys.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/transforms.h> +#include <xmlsec/dl.h> + +/** + * Crypto Init/shutdown + */ +XMLSEC_EXPORT int xmlSecCryptoInit (void); +XMLSEC_EXPORT int xmlSecCryptoShutdown (void); +XMLSEC_EXPORT int xmlSecCryptoKeysMngrInit (xmlSecKeysMngrPtr mngr); + +/** + * Key data ids + */ +#define xmlSecKeyDataAesId xmlSecKeyDataAesGetKlass() +XMLSEC_EXPORT xmlSecKeyDataId xmlSecKeyDataAesGetKlass (void); +#define xmlSecKeyDataDesId xmlSecKeyDataDesGetKlass() +XMLSEC_EXPORT xmlSecKeyDataId xmlSecKeyDataDesGetKlass (void); +#define xmlSecKeyDataDsaId xmlSecKeyDataDsaGetKlass() +XMLSEC_EXPORT xmlSecKeyDataId xmlSecKeyDataDsaGetKlass (void); +#define xmlSecKeyDataHmacId xmlSecKeyDataHmacGetKlass() +XMLSEC_EXPORT xmlSecKeyDataId xmlSecKeyDataHmacGetKlass (void); +#define xmlSecKeyDataRsaId xmlSecKeyDataRsaGetKlass() +XMLSEC_EXPORT xmlSecKeyDataId xmlSecKeyDataRsaGetKlass (void); +#define xmlSecKeyDataX509Id xmlSecKeyDataX509GetKlass() +XMLSEC_EXPORT xmlSecKeyDataId xmlSecKeyDataX509GetKlass (void); +#define xmlSecKeyDataRawX509CertId xmlSecKeyDataRawX509CertGetKlass() +XMLSEC_EXPORT xmlSecKeyDataId xmlSecKeyDataRawX509CertGetKlass(void); + +/** + * Key data store ids + */ +#define xmlSecX509StoreId xmlSecX509StoreGetKlass() +XMLSEC_EXPORT xmlSecKeyDataStoreId xmlSecX509StoreGetKlass (void); + +/** + * Crypto transforms ids + */ +#define xmlSecTransformAes128CbcId xmlSecTransformAes128CbcGetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformAes128CbcGetKlass(void); +#define xmlSecTransformAes192CbcId xmlSecTransformAes192CbcGetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformAes192CbcGetKlass(void); +#define xmlSecTransformAes256CbcId xmlSecTransformAes256CbcGetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformAes256CbcGetKlass(void); +#define xmlSecTransformKWAes128Id xmlSecTransformKWAes128GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformKWAes128GetKlass (void); +#define xmlSecTransformKWAes192Id xmlSecTransformKWAes192GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformKWAes192GetKlass (void); +#define xmlSecTransformKWAes256Id xmlSecTransformKWAes256GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformKWAes256GetKlass (void); +#define xmlSecTransformDes3CbcId xmlSecTransformDes3CbcGetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformDes3CbcGetKlass (void); +#define xmlSecTransformKWDes3Id xmlSecTransformKWDes3GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformKWDes3GetKlass (void); +#define xmlSecTransformDsaSha1Id xmlSecTransformDsaSha1GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformDsaSha1GetKlass (void); +#define xmlSecTransformHmacSha1Id xmlSecTransformHmacSha1GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformHmacSha1GetKlass (void); +#define xmlSecTransformHmacRipemd160Id xmlSecTransformHmacRipemd160GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformHmacRipemd160GetKlass(void); +#define xmlSecTransformHmacMd5Id xmlSecTransformHmacMd5GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformHmacMd5GetKlass (void); +#define xmlSecTransformRipemd160Id xmlSecTransformRipemd160GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformRipemd160GetKlass(void); +#define xmlSecTransformRsaSha1Id xmlSecTransformRsaSha1GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformRsaSha1GetKlass (void); +#define xmlSecTransformRsaPkcs1Id xmlSecTransformRsaPkcs1GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformRsaPkcs1GetKlass (void); +#define xmlSecTransformRsaOaepId xmlSecTransformRsaOaepGetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformRsaOaepGetKlass (void); +#define xmlSecTransformSha1Id xmlSecTransformSha1GetKlass() +XMLSEC_EXPORT xmlSecTransformId xmlSecTransformSha1GetKlass (void); + +/** + * High level routines form xmlsec command line utility + */ +XMLSEC_EXPORT int xmlSecCryptoAppInit (const char* config); +XMLSEC_EXPORT int xmlSecCryptoAppShutdown (void); +XMLSEC_EXPORT int xmlSecCryptoAppDefaultKeysMngrInit (xmlSecKeysMngrPtr mngr); +XMLSEC_EXPORT int xmlSecCryptoAppDefaultKeysMngrAdoptKey (xmlSecKeysMngrPtr mngr, + xmlSecKeyPtr key); +XMLSEC_EXPORT int xmlSecCryptoAppDefaultKeysMngrLoad (xmlSecKeysMngrPtr mngr, + const char* uri); +XMLSEC_EXPORT int xmlSecCryptoAppDefaultKeysMngrSave (xmlSecKeysMngrPtr mngr, + const char* filename, + xmlSecKeyDataType type); +XMLSEC_EXPORT int xmlSecCryptoAppKeysMngrCertLoad (xmlSecKeysMngrPtr mngr, + const char *filename, + xmlSecKeyDataFormat format, + xmlSecKeyDataType type); +XMLSEC_EXPORT xmlSecKeyPtr xmlSecCryptoAppKeyLoad (const char *filename, + xmlSecKeyDataFormat format, + const char *pwd, + void* pwdCallback, + void* pwdCallbackCtx); +XMLSEC_EXPORT xmlSecKeyPtr xmlSecCryptoAppPkcs12Load (const char* filename, + const char* pwd, + void* pwdCallback, + void* pwdCallbackCtx); +XMLSEC_EXPORT int xmlSecCryptoAppKeyCertLoad (xmlSecKeyPtr key, + const char* filename, + xmlSecKeyDataFormat format); +XMLSEC_EXPORT void* xmlSecCryptoAppGetDefaultPwdCallback(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XMLSEC_NO_CRYPTO_DYNAMIC_LOADING */ + +#endif /* __XMLSEC_APP_H__ */ + diff --git a/include/xmlsec/crypto.h b/include/xmlsec/crypto.h index 269c3897..25d71221 100644 --- a/include/xmlsec/crypto.h +++ b/include/xmlsec/crypto.h @@ -21,6 +21,13 @@ extern "C" { #ifndef IN_XMLSEC #ifndef IN_XMLSEC_CRYPTO +#if defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) +#error Dynamic loading for xmlsec-crypto libraries is disabled during library compilation +#endif /* defined(XMLSEC_NO_CRYPTO_DYNAMIC_LOADING) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + +#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING +#include <xmlsec/app.h> +#else /* XMLSEC_CRYPTO_DYNAMIC_LOADING */ #ifdef XMLSEC_CRYPTO_OPENSSL #include <xmlsec/openssl/app.h> #include <xmlsec/openssl/crypto.h> @@ -41,6 +48,7 @@ extern "C" { #endif /* XMLSEC_CRYPTO_GNUTLS */ #endif /* XMLSEC_CRYPTO_NSS */ #endif /* XMLSEC_CRYPTO_OPENSSL */ +#endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */ #endif /* IN_XMLSEC_CRYPTO */ #endif /* IN_XMLSEC */ diff --git a/include/xmlsec/dl.h b/include/xmlsec/dl.h new file mode 100644 index 00000000..8fc1da06 --- /dev/null +++ b/include/xmlsec/dl.h @@ -0,0 +1,56 @@ +/** + * XML Security Library (http://www.aleksey.com/xmlsec). + * + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + */ +#ifndef __XMLSEC_DL_H__ +#define __XMLSEC_DL_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _xmlSecCryptoDLFunctions xmlSecCryptoDLFunctions, + *xmlSecCryptoDLFunctionsPtr; + +XMLSEC_EXPORT int xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms + (xmlSecCryptoDLFunctionsPtr functions); + + + +#ifndef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING + +#include <libxml/tree.h> +#include <libxml/xmlIO.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/keysdata.h> +#include <xmlsec/keys.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/transforms.h> + +/** + * Dynamic load functions + */ +XMLSEC_EXPORT int xmlSecCryptoDLInit (void); +XMLSEC_EXPORT int xmlSecCryptoDLShutdown (void); + +XMLSEC_EXPORT int xmlSecCryptoDLLoadLibrary (const xmlChar* crypto); +XMLSEC_EXPORT xmlSecCryptoDLFunctionsPtr xmlSecCryptoDLGetLibraryFunctions(const xmlChar* crypto); +XMLSEC_EXPORT int xmlSecCryptoDLUnloadLibrary (const xmlChar* crypto); + +XMLSEC_EXPORT int xmlSecCryptoDLSetFunctions (xmlSecCryptoDLFunctionsPtr functions); +XMLSEC_EXPORT xmlSecCryptoDLFunctionsPtr xmlSecCryptoDLGetFunctions (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XMLSEC_NO_CRYPTO_DYNAMIC_LOADING */ + +#endif /* __XMLSEC_APP_H__ */ + diff --git a/include/xmlsec/gnutls/app.h b/include/xmlsec/gnutls/app.h index f983a745..602f966f 100644 --- a/include/xmlsec/gnutls/app.h +++ b/include/xmlsec/gnutls/app.h @@ -40,8 +40,6 @@ XMLSEC_CRYPTO_EXPORT int xmlSecGnuTLSAppKeysMngrCertLoad (xmlSecKeysMngrPtr mng const char *filename, xmlSecKeyDataFormat format, xmlSecKeyDataType type); -XMLSEC_CRYPTO_EXPORT int xmlSecGnuTLSAppKeysMngrAddCertsPath (xmlSecKeysMngrPtr mngr, - const char *path); #endif /* XMLSEC_NO_X509 */ @@ -62,6 +60,7 @@ XMLSEC_CRYPTO_EXPORT int xmlSecGnuTLSAppKeyCertLoad (xmlSecKeyPtr key, const char* filename, xmlSecKeyDataFormat format); #endif /* XMLSEC_NO_X509 */ +XMLSEC_CRYPTO_EXPORT void* xmlSecGnuTLSAppGetDefaultPwdCallback (void); #ifdef __cplusplus } diff --git a/include/xmlsec/gnutls/crypto.h b/include/xmlsec/gnutls/crypto.h index 22438e4c..08b93c87 100644 --- a/include/xmlsec/gnutls/crypto.h +++ b/include/xmlsec/gnutls/crypto.h @@ -16,6 +16,9 @@ extern "C" { #include <xmlsec/xmlsec.h> #include <xmlsec/keys.h> #include <xmlsec/transforms.h> +#include <xmlsec/dl.h> + +XMLSEC_CRYPTO_EXPORT xmlSecCryptoDLFunctionsPtr xmlSecCryptoGetFunctions_gnutls(void); /** * Init shutdown diff --git a/include/xmlsec/gnutls/symbols.h b/include/xmlsec/gnutls/symbols.h index 50bff111..32dde8a5 100644 --- a/include/xmlsec/gnutls/symbols.h +++ b/include/xmlsec/gnutls/symbols.h @@ -9,6 +9,10 @@ #ifndef __XMLSEC_GNUTLS_SYMBOLS_H__ #define __XMLSEC_GNUTLS_SYMBOLS_H__ +#if !defined(IN_XMLSEC) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) +#error To disable dynamic loading of xmlsec-crypto libraries undefine XMLSEC_CRYPTO_DYNAMIC_LOADING +#endif /* !defined(IN_XMLSEC) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -73,10 +77,10 @@ extern "C" { #define xmlSecCryptoAppDefaultKeysMngrLoad xmlSecGnuTLSAppDefaultKeysMngrLoad #define xmlSecCryptoAppDefaultKeysMngrSave xmlSecGnuTLSAppDefaultKeysMngrSave #define xmlSecCryptoAppKeysMngrCertLoad xmlSecGnuTLSAppKeysMngrCertLoad -#define xmlSecCryptoAppKeysMngrAddCertsPath xmlSecGnuTLSAppKeysMngrAddCertsPath #define xmlSecCryptoAppKeyLoad xmlSecGnuTLSAppKeyLoad #define xmlSecCryptoAppPkcs12Load xmlSecGnuTLSAppPkcs12Load #define xmlSecCryptoAppKeyCertLoad xmlSecGnuTLSAppKeyCertLoad +#define xmlSecCryptoAppGetDefaultPwdCallback xmlSecGnuTLSAppGetDefaultPwdCallback #endif /* XMLSEC_CRYPTO_GNUTLS */ diff --git a/include/xmlsec/keysdata.h b/include/xmlsec/keysdata.h index 86c2d605..5d85e360 100644 --- a/include/xmlsec/keysdata.h +++ b/include/xmlsec/keysdata.h @@ -357,7 +357,7 @@ XMLSEC_EXPORT int xmlSecKeyDataBinWrite (xmlSecKeyDataId id, * * The "unknown" id. */ -#define xmlSecKeyDataIdUnknown NULL +#define xmlSecKeyDataIdUnknown ((xmlSecKeyDataId)NULL) /** * xmlSecKeyDataInitMethod: diff --git a/include/xmlsec/keysmngr.h b/include/xmlsec/keysmngr.h index dbd7e242..aa42697f 100644 --- a/include/xmlsec/keysmngr.h +++ b/include/xmlsec/keysmngr.h @@ -158,7 +158,7 @@ XMLSEC_EXPORT xmlSecKeyPtr xmlSecKeyStoreFindKey (xmlSecKeyStorePtr store, * * The "unknown" id. */ -#define xmlSecKeyStoreIdUnknown NULL +#define xmlSecKeyStoreIdUnknown ((xmlSecKeyDataStoreId)NULL) /** * xmlSecKeyStoreInitializeMethod: diff --git a/include/xmlsec/nss/app.h b/include/xmlsec/nss/app.h index 4938fea9..a7093edf 100644 --- a/include/xmlsec/nss/app.h +++ b/include/xmlsec/nss/app.h @@ -61,6 +61,7 @@ XMLSEC_CRYPTO_EXPORT int xmlSecNssAppKeyCertLoad (xmlSecKeyPtr key, const char* filename, xmlSecKeyDataFormat format); #endif /* XMLSEC_NO_X509 */ +XMLSEC_CRYPTO_EXPORT void* xmlSecNssAppGetDefaultPwdCallback(void); #ifdef __cplusplus } diff --git a/include/xmlsec/nss/crypto.h b/include/xmlsec/nss/crypto.h index 6db7cc11..8c191df3 100644 --- a/include/xmlsec/nss/crypto.h +++ b/include/xmlsec/nss/crypto.h @@ -17,6 +17,9 @@ extern "C" { #include <xmlsec/xmlsec.h> #include <xmlsec/keys.h> #include <xmlsec/transforms.h> +#include <xmlsec/dl.h> + +XMLSEC_CRYPTO_EXPORT xmlSecCryptoDLFunctionsPtr xmlSecCryptoGetFunctions_nss(void); /** * Init shutdown diff --git a/include/xmlsec/nss/symbols.h b/include/xmlsec/nss/symbols.h index 33ace85a..3a62d4c1 100644 --- a/include/xmlsec/nss/symbols.h +++ b/include/xmlsec/nss/symbols.h @@ -10,6 +10,11 @@ #ifndef __XMLSEC_NSS_SYMBOLS_H__ #define __XMLSEC_NSS_SYMBOLS_H__ +#if !defined(IN_XMLSEC) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) +#error To disable dynamic loading of xmlsec-crypto libraries undefine XMLSEC_CRYPTO_DYNAMIC_LOADING +#endif /* !defined(IN_XMLSEC) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -77,6 +82,7 @@ extern "C" { #define xmlSecCryptoAppKeyLoad xmlSecNssAppKeyLoad #define xmlSecCryptoAppPkcs12Load xmlSecNssAppPkcs12Load #define xmlSecCryptoAppKeyCertLoad xmlSecNssAppKeyCertLoad +#define xmlSecCryptoAppGetDefaultPwdCallback xmlSecNssAppGetDefaultPwdCallback #endif /* XMLSEC_CRYPTO_NSS */ diff --git a/include/xmlsec/openssl/app.h b/include/xmlsec/openssl/app.h index ca7e0f46..6d8c2628 100644 --- a/include/xmlsec/openssl/app.h +++ b/include/xmlsec/openssl/app.h @@ -105,6 +105,9 @@ XMLSEC_CRYPTO_EXPORT int xmlSecOpenSSLAppKeyCertLoadBIO (xmlSecKeyPtr key, xmlSecKeyDataFormat format); #endif /* XMLSEC_NO_X509 */ +XMLSEC_CRYPTO_EXPORT void* xmlSecOpenSSLAppGetDefaultPwdCallback(void); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/include/xmlsec/openssl/crypto.h b/include/xmlsec/openssl/crypto.h index 6723da61..458b50ba 100644 --- a/include/xmlsec/openssl/crypto.h +++ b/include/xmlsec/openssl/crypto.h @@ -16,10 +16,13 @@ extern "C" { #include <xmlsec/xmlsec.h> #include <xmlsec/keys.h> #include <xmlsec/transforms.h> +#include <xmlsec/dl.h> #include <openssl/err.h> +XMLSEC_CRYPTO_EXPORT xmlSecCryptoDLFunctionsPtr xmlSecCryptoGetFunctions_openssl(void); + /** * Init shutdown */ diff --git a/include/xmlsec/openssl/symbols.h b/include/xmlsec/openssl/symbols.h index 2c5862c1..05c1f1c6 100644 --- a/include/xmlsec/openssl/symbols.h +++ b/include/xmlsec/openssl/symbols.h @@ -9,11 +9,14 @@ #ifndef __XMLSEC_OPENSSL_SYMBOLS_H__ #define __XMLSEC_OPENSSL_SYMBOLS_H__ +#if !defined(IN_XMLSEC) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) +#error To disable dynamic loading of xmlsec-crypto libraries undefine XMLSEC_CRYPTO_DYNAMIC_LOADING +#endif /* !defined(IN_XMLSEC) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - /** * Defines for writing simple code */ @@ -74,10 +77,14 @@ extern "C" { #define xmlSecCryptoAppDefaultKeysMngrLoad xmlSecOpenSSLAppDefaultKeysMngrLoad #define xmlSecCryptoAppDefaultKeysMngrSave xmlSecOpenSSLAppDefaultKeysMngrSave #define xmlSecCryptoAppKeysMngrCertLoad xmlSecOpenSSLAppKeysMngrCertLoad -#define xmlSecCryptoAppKeysMngrAddCertsPath xmlSecOpenSSLAppKeysMngrAddCertsPath #define xmlSecCryptoAppKeyLoad xmlSecOpenSSLAppKeyLoad #define xmlSecCryptoAppPkcs12Load xmlSecOpenSSLAppPkcs12Load #define xmlSecCryptoAppKeyCertLoad xmlSecOpenSSLAppKeyCertLoad +#define xmlSecCryptoAppGetDefaultPwdCallback xmlSecOpenSSLAppGetDefaultPwdCallback + + +/* todo: this should go away on next API refresh */ +#define xmlSecCryptoAppKeysMngrAddCertsPath xmlSecOpenSSLAppKeysMngrAddCertsPath #endif /* XMLSEC_CRYPTO_OPENSSL */ diff --git a/include/xmlsec/private.h b/include/xmlsec/private.h new file mode 100644 index 00000000..b50021c3 --- /dev/null +++ b/include/xmlsec/private.h @@ -0,0 +1,155 @@ +/** + * XML Security Library (http://www.aleksey.com/xmlsec). + * + * These are internal private declarations. You don't want to use this file + * unless you are building xmlsec or xmlsec-<crypto> library + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + */ +#ifndef __XMLSEC_PRIVATE_H__ +#define __XMLSEC_PRIVATE_H__ + +#ifndef XMLSEC_PRIVATE +#error "xmlsec/private.h file contains private xmlsec definitions and should not be used outside xmlsec or xmlsec-<crypto> libraries" +#endif /* XMLSEC_PRIVATE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include <libxml/tree.h> +#include <libxml/xmlIO.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/keysdata.h> +#include <xmlsec/keys.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/transforms.h> + + +/** + * Crypto Init/shutdown + */ +typedef int (*xmlSecCryptoInitMethod) (void); +typedef int (*xmlSecCryptoShutdownMethod) (void); +typedef int (*xmlSecCryptoKeysMngrInitMethod) (xmlSecKeysMngrPtr mngr); + +/** + * Key data ids + */ +typedef xmlSecKeyDataId (*xmlSecCryptoKeyDataGetKlassMethod) (void); + +/** + * Key data store ids + */ +typedef xmlSecKeyDataStoreId (*xmlSecCryptoKeyDataStoreGetKlassMethod)(void); + +/** + * Crypto transforms ids + */ +typedef xmlSecTransformId (*xmlSecCryptoTransformGetKlassMethod) (void); + +/** + * High level routines form xmlsec command line utility + */ +typedef int (*xmlSecCryptoAppInitMethod) (const char* config); +typedef int (*xmlSecCryptoAppShutdownMethod) (void); +typedef int (*xmlSecCryptoAppDefaultKeysMngrInitMethod) + (xmlSecKeysMngrPtr mngr); +typedef int (*xmlSecCryptoAppDefaultKeysMngrAdoptKeyMethod) + (xmlSecKeysMngrPtr mngr, + xmlSecKeyPtr key); +typedef int (*xmlSecCryptoAppDefaultKeysMngrLoadMethod) + (xmlSecKeysMngrPtr mngr, + const char* uri); +typedef int (*xmlSecCryptoAppDefaultKeysMngrSaveMethod) + (xmlSecKeysMngrPtr mngr, + const char* filename, + xmlSecKeyDataType type); +typedef int (*xmlSecCryptoAppKeysMngrCertLoadMethod)(xmlSecKeysMngrPtr mngr, + const char *filename, + xmlSecKeyDataFormat format, + xmlSecKeyDataType type); +typedef xmlSecKeyPtr (*xmlSecCryptoAppKeyLoadMethod) (const char *filename, + xmlSecKeyDataFormat format, + const char *pwd, + void* pwdCallback, + void* pwdCallbackCtx); +typedef xmlSecKeyPtr (*xmlSecCryptoAppPkcs12LoadMethod) (const char* filename, + const char* pwd, + void* pwdCallback, + void* pwdCallbackCtx); +typedef int (*xmlSecCryptoAppKeyCertLoadMethod) (xmlSecKeyPtr key, + const char* filename, + xmlSecKeyDataFormat format); + +struct _xmlSecCryptoDLFunctions { + /** + * Crypto Init/shutdown + */ + xmlSecCryptoInitMethod cryptoInit; + xmlSecCryptoShutdownMethod cryptoShutdown; + xmlSecCryptoKeysMngrInitMethod cryptoKeysMngrInit; + + /** + * Key data ids + */ + xmlSecCryptoKeyDataGetKlassMethod keyDataAesGetKlass; + xmlSecCryptoKeyDataGetKlassMethod keyDataDesGetKlass; + xmlSecCryptoKeyDataGetKlassMethod keyDataDsaGetKlass; + xmlSecCryptoKeyDataGetKlassMethod keyDataHmacGetKlass; + xmlSecCryptoKeyDataGetKlassMethod keyDataRsaGetKlass; + xmlSecCryptoKeyDataGetKlassMethod keyDataX509GetKlass; + xmlSecCryptoKeyDataGetKlassMethod keyDataRawX509CertGetKlass; + + /** + * Key data store ids + */ + xmlSecCryptoKeyDataStoreGetKlassMethod x509StoreGetKlass; + + /** + * Crypto transforms ids + */ + xmlSecCryptoTransformGetKlassMethod transformAes128CbcGetKlass; + xmlSecCryptoTransformGetKlassMethod transformAes192CbcGetKlass; + xmlSecCryptoTransformGetKlassMethod transformAes256CbcGetKlass; + xmlSecCryptoTransformGetKlassMethod transformKWAes128GetKlass; + xmlSecCryptoTransformGetKlassMethod transformKWAes192GetKlass; + xmlSecCryptoTransformGetKlassMethod transformKWAes256GetKlass; + xmlSecCryptoTransformGetKlassMethod transformDes3CbcGetKlass; + xmlSecCryptoTransformGetKlassMethod transformKWDes3GetKlass; + xmlSecCryptoTransformGetKlassMethod transformDsaSha1GetKlass; + xmlSecCryptoTransformGetKlassMethod transformHmacSha1GetKlass; + xmlSecCryptoTransformGetKlassMethod transformHmacRipemd160GetKlass; + xmlSecCryptoTransformGetKlassMethod transformHmacMd5GetKlass; + xmlSecCryptoTransformGetKlassMethod transformRipemd160GetKlass; + xmlSecCryptoTransformGetKlassMethod transformRsaSha1GetKlass; + xmlSecCryptoTransformGetKlassMethod transformRsaPkcs1GetKlass; + xmlSecCryptoTransformGetKlassMethod transformRsaOaepGetKlass; + xmlSecCryptoTransformGetKlassMethod transformSha1GetKlass; + + /** + * High level routines form xmlsec command line utility + */ + xmlSecCryptoAppInitMethod cryptoAppInit; + xmlSecCryptoAppShutdownMethod cryptoAppShutdown; + xmlSecCryptoAppDefaultKeysMngrInitMethod cryptoAppDefaultKeysMngrInit; + xmlSecCryptoAppDefaultKeysMngrAdoptKeyMethod cryptoAppDefaultKeysMngrAdoptKey; + xmlSecCryptoAppDefaultKeysMngrLoadMethod cryptoAppDefaultKeysMngrLoad; + xmlSecCryptoAppDefaultKeysMngrSaveMethod cryptoAppDefaultKeysMngrSave; + xmlSecCryptoAppKeysMngrCertLoadMethod cryptoAppKeysMngrCertLoad; + xmlSecCryptoAppKeyLoadMethod cryptoAppKeyLoad; + xmlSecCryptoAppPkcs12LoadMethod cryptoAppPkcs12Load; + xmlSecCryptoAppKeyCertLoadMethod cryptoAppKeyCertLoad; + void* cryptoAppDefaultPwdCallback; +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __XMLSEC_PRIVATE_H__ */ + diff --git a/include/xmlsec/skeleton/app.h b/include/xmlsec/skeleton/app.h index e68d5bf2..bed0f5e2 100644 --- a/include/xmlsec/skeleton/app.h +++ b/include/xmlsec/skeleton/app.h @@ -40,8 +40,6 @@ XMLSEC_CRYPTO_EXPORT int xmlSecSkeletonAppKeysMngrCertLoad (xmlSecKeysMngrPtr mn const char *filename, xmlSecKeyDataFormat format, xmlSecKeyDataType type); -XMLSEC_CRYPTO_EXPORT int xmlSecSkeletonAppKeysMngrAddCertsPath (xmlSecKeysMngrPtr mngr, - const char *path); #endif /* XMLSEC_NO_X509 */ @@ -63,6 +61,8 @@ XMLSEC_CRYPTO_EXPORT int xmlSecSkeletonAppKeyCertLoad (xmlSecKeyPtr key, xmlSecKeyDataFormat format); #endif /* XMLSEC_NO_X509 */ +XMLSEC_CRYPTO_EXPORT void* xmlSecSkeletonAppGetDefaultPwdCallback (void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/include/xmlsec/skeleton/crypto.h b/include/xmlsec/skeleton/crypto.h index bc644322..3b32c237 100644 --- a/include/xmlsec/skeleton/crypto.h +++ b/include/xmlsec/skeleton/crypto.h @@ -16,6 +16,9 @@ extern "C" { #include <xmlsec/xmlsec.h> #include <xmlsec/keys.h> #include <xmlsec/transforms.h> +#include <xmlsec/dl.h> + +XMLSEC_CRYPTO_EXPORT xmlSecCryptoDLFunctionsPtr xmlSecCryptoGetFunctions_skeleton(void); /** * Init shutdown diff --git a/include/xmlsec/skeleton/symbols.h b/include/xmlsec/skeleton/symbols.h index 279d7eee..d8456e71 100644 --- a/include/xmlsec/skeleton/symbols.h +++ b/include/xmlsec/skeleton/symbols.h @@ -9,6 +9,10 @@ #ifndef __XMLSEC_SKELETON_SYMBOLS_H__ #define __XMLSEC_SKELETON_SYMBOLS_H__ +#if !defined(IN_XMLSEC) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) +#error To disable dynamic loading of xmlsec-crypto libraries undefine XMLSEC_CRYPTO_DYNAMIC_LOADING +#endif /* !defined(IN_XMLSEC) && defined(XMLSEC_CRYPTO_DYNAMIC_LOADING) */ + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -73,10 +77,10 @@ extern "C" { #define xmlSecCryptoAppDefaultKeysMngrLoad xmlSecSkeletonAppDefaultKeysMngrLoad #define xmlSecCryptoAppDefaultKeysMngrSave xmlSecSkeletonAppDefaultKeysMngrSave #define xmlSecCryptoAppKeysMngrCertLoad xmlSecSkeletonAppKeysMngrCertLoad -#define xmlSecCryptoAppKeysMngrAddCertsPath xmlSecSkeletonAppKeysMngrAddCertsPath #define xmlSecCryptoAppKeyLoad xmlSecSkeletonAppKeyLoad #define xmlSecCryptoAppPkcs12Load xmlSecSkeletonAppPkcs12Load #define xmlSecCryptoAppKeyCertLoad xmlSecSkeletonAppKeyCertLoad +#define xmlSecCryptoAppGetDefaultPwdCallback xmlSecSkeletonAppGetDefaultPwdCallback #endif /* XMLSEC_CRYPTO_SKELETON */ diff --git a/include/xmlsec/transforms.h b/include/xmlsec/transforms.h index 5a6fdb44..16ef0ea4 100644 --- a/include/xmlsec/transforms.h +++ b/include/xmlsec/transforms.h @@ -847,7 +847,7 @@ XMLSEC_EXPORT void xmlSecTransformIdListDebugXmlDump(xmlSecPtrListPtr list, * * The "unknown" transform id (NULL). */ -#define xmlSecTransformIdUnknown NULL +#define xmlSecTransformIdUnknown ((xmlSecTransformId)NULL) /** * xmlSecTransformBase64Id: diff --git a/src/Makefile.am b/src/Makefile.am index 420e3ea3..02dcce8d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,6 +3,7 @@ NULL = SUBDIRS = $(XMLSEC_CRYPTO_LIST) INCLUDES = \ + -DPACKAGE=\"@PACKAGE@\" \ -I$(top_srcdir) \ -I$(top_srcdir)/include \ $(XMLSEC_DEFINES) \ @@ -12,6 +13,8 @@ INCLUDES = \ EXTRA_DIST = \ globals.h \ + ltdl.h ltdl.c \ + xmlsec-ltdl.h xmlsec-ltdl.c.patch \ skeleton \ $(XMLSEC_CRYPTO_DISABLED_LIST) \ $(NULL) @@ -20,10 +23,13 @@ lib_LTLIBRARIES = \ libxmlsec1.la \ $(NULL) -libxmlsec1_la_SOURCES =\ +libxmlsec1_la_SOURCES = \ + $(LTDL_SOURCE_FILES) \ + app.c \ base64.c \ buffer.c \ c14n.c \ + dl.c \ enveloped.c \ errors.c \ io.c \ @@ -57,3 +63,27 @@ libxmlsec1_la_LDFLAGS = \ -version-info @XMLSEC_VERSION_INFO@ \ $(NULL) +if XMLSEC_APPS_NO_CRYPTO_DYNAMIC_LOADING +LTDL_SOURCE_FILES = \ + $(NULL) +else +LTDL_SOURCE_FILES = \ + xmlsec-ltdl.c \ + $(NULL) + +LTDL_PARSE = \ + sed s/ltdl.h/xmlsec-ltdl.h/g | \ + sed s/lt_/xmlsec_lt_/g | \ + sed s/ltdl_/xmlsec_ltdl_/g \ + $(NULL) + +xmlsec-ltdl.c: xmlsec-ltdl.c.patch xmlsec-ltdl.h ltdl.c + @(cat ltdl.c | $(LTDL_PARSE) > xmlsec-ltdl.c && patch -p0 < xmlsec-ltdl.c.patch) + +xmlsec-ltdl.h: ltdl.h + @(cat ltdl.h | $(LTDL_PARSE) > xmlsec-ltdl.h) + +endif + + + diff --git a/src/app.c b/src/app.c new file mode 100644 index 00000000..5857df88 --- /dev/null +++ b/src/app.c @@ -0,0 +1,645 @@ +/** + * XML Security Library (http://www.aleksey.com/xmlsec). + * + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + */ +#include "globals.h" + +#ifndef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <time.h> + +#include <libxml/tree.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/app.h> +#include <xmlsec/list.h> +#include <xmlsec/keysdata.h> +#include <xmlsec/keys.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/transforms.h> +#include <xmlsec/private.h> +#include <xmlsec/errors.h> + + +/****************************************************************************** + * + * Crypto Init/shutdown + * + *****************************************************************************/ +/** + * xmlSecCryptoInit: + * + * XMLSec library specific crypto engine initialization. + * + * Returns 0 on success or a negative value otherwise. + */ +int +xmlSecCryptoInit(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoInit == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoInit", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoInit()); +} + +/** + * xmlSecCryptoShutdown: + * + * XMLSec library specific crypto engine shutdown. + * + * Returns 0 on success or a negative value otherwise. + */ +int +xmlSecCryptoShutdown(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoShutdown == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoShutdown", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoShutdown()); +} + +/** + * xmlSecCryptoKeysMngrInit: + * @mngr: the pointer to keys manager. + * + * Adds crypto specific key data stores in keys manager. + * + * Returns 0 on success or a negative value otherwise. + */ +int +xmlSecCryptoKeysMngrInit(xmlSecKeysMngrPtr mngr) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoKeysMngrInit == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoKeysMngrInit", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoKeysMngrInit(mngr)); +} + +/****************************************************************************** + * + * Key data ids + * + *****************************************************************************/ +/** + * xmlSecKeyDataAesGetKlass: + * + * The AES key data klass. + * + * Returns AES key data klass. + */ +xmlSecKeyDataId +xmlSecKeyDataAesGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->keyDataAesGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "keyDataAesId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecKeyDataIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->keyDataAesGetKlass()); +} + +xmlSecKeyDataId +xmlSecKeyDataDesGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->keyDataDesGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "keyDataDesId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecKeyDataIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->keyDataDesGetKlass()); +} + +xmlSecKeyDataId +xmlSecKeyDataDsaGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->keyDataDsaGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "keyDataDsaId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecKeyDataIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->keyDataDsaGetKlass()); +} + +xmlSecKeyDataId +xmlSecKeyDataHmacGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->keyDataHmacGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "keyDataHmacId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecKeyDataIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->keyDataHmacGetKlass()); +} + +xmlSecKeyDataId +xmlSecKeyDataRsaGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->keyDataRsaGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "keyDataRsaId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecKeyDataIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->keyDataRsaGetKlass()); +} + +xmlSecKeyDataId +xmlSecKeyDataX509GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->keyDataX509GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "keyDataX509Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecKeyDataIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->keyDataX509GetKlass()); +} + +xmlSecKeyDataId +xmlSecKeyDataRawX509CertGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->keyDataRawX509CertGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "keyDataRawX509CertId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecKeyDataIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->keyDataRawX509CertGetKlass()); +} + +/****************************************************************************** + * + * Key data store ids + * + *****************************************************************************/ +xmlSecKeyDataStoreId +xmlSecX509StoreGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->x509StoreGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "x509StoreId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecKeyStoreIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->x509StoreGetKlass()); +} + +/****************************************************************************** + * + * Crypto transforms ids + * + *****************************************************************************/ +xmlSecTransformId +xmlSecTransformAes128CbcGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformAes128CbcGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformAes128CbcId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformAes128CbcGetKlass()); +} + +xmlSecTransformId +xmlSecTransformAes192CbcGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformAes192CbcGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformAes192CbcId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformAes192CbcGetKlass()); +} + +xmlSecTransformId +xmlSecTransformAes256CbcGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformAes256CbcGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformAes256CbcId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformAes256CbcGetKlass()); +} + +xmlSecTransformId +xmlSecTransformKWAes128GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformKWAes128GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformKWAes128Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformKWAes128GetKlass()); +} + +xmlSecTransformId +xmlSecTransformKWAes192GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformKWAes192GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformKWAes192Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformKWAes192GetKlass()); +} + +xmlSecTransformId +xmlSecTransformKWAes256GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformKWAes256GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformKWAes256Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformKWAes256GetKlass()); +} + +xmlSecTransformId +xmlSecTransformDes3CbcGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformDes3CbcGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformDes3CbcId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformDes3CbcGetKlass()); +} + +xmlSecTransformId +xmlSecTransformKWDes3GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformKWDes3GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformKWDes3Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformKWDes3GetKlass()); +} + +xmlSecTransformId +xmlSecTransformDsaSha1GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformDsaSha1GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformDsaSha1Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformDsaSha1GetKlass()); +} + +xmlSecTransformId +xmlSecTransformHmacSha1GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformHmacSha1GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformHmacSha1Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformHmacSha1GetKlass()); +} + +xmlSecTransformId +xmlSecTransformHmacRipemd160GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformHmacRipemd160GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformHmacRipemd160Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformHmacRipemd160GetKlass()); +} + +xmlSecTransformId +xmlSecTransformHmacMd5GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformHmacMd5GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformHmacMd5Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformHmacMd5GetKlass()); +} + +xmlSecTransformId +xmlSecTransformRipemd160GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformRipemd160GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformRipemd160Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformRipemd160GetKlass()); +} + +xmlSecTransformId +xmlSecTransformRsaSha1GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformRsaSha1GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformRsaSha1Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformRsaSha1GetKlass()); +} + +xmlSecTransformId +xmlSecTransformRsaPkcs1GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformRsaPkcs1GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformRsaPkcs1Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformRsaPkcs1GetKlass()); +} + +xmlSecTransformId +xmlSecTransformRsaOaepGetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformRsaOaepGetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformRsaOaepId", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformRsaOaepGetKlass()); +} + +xmlSecTransformId +xmlSecTransformSha1GetKlass(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->transformSha1GetKlass == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "transformSha1Id", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(xmlSecTransformIdUnknown); + } + + return(xmlSecCryptoDLGetFunctions()->transformSha1GetKlass()); +} + +/****************************************************************************** + * + * High level routines form xmlsec command line utility + * + *****************************************************************************/ +int +xmlSecCryptoAppInit(const char* config) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoAppInit == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoAppInit", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppInit(config)); +} + + +int +xmlSecCryptoAppShutdown(void) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoAppShutdown == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoAppShutdown", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppShutdown()); +} + + +int +xmlSecCryptoAppDefaultKeysMngrInit(xmlSecKeysMngrPtr mngr) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoAppDefaultKeysMngrInit == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoAppDefaultKeysMngrInit", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppDefaultKeysMngrInit(mngr)); +} + + +int +xmlSecCryptoAppDefaultKeysMngrAdoptKey(xmlSecKeysMngrPtr mngr, xmlSecKeyPtr key) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoAppDefaultKeysMngrAdoptKey == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoAppDefaultKeysMngrAdoptKey", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppDefaultKeysMngrAdoptKey(mngr, key)); +} + + +int +xmlSecCryptoAppDefaultKeysMngrLoad(xmlSecKeysMngrPtr mngr, const char* uri) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoAppDefaultKeysMngrLoad == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoAppDefaultKeysMngrLoad", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppDefaultKeysMngrLoad(mngr, uri)); +} + + +int +xmlSecCryptoAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filename, + xmlSecKeyDataType type) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoAppDefaultKeysMngrSave == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoAppDefaultKeysMngrSave", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppDefaultKeysMngrSave(mngr, filename, type)); +} + +int +xmlSecCryptoAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, const char *filename, + xmlSecKeyDataFormat format, xmlSecKeyDataType type) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoAppKeysMngrCertLoad == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoAppKeysMngrCertLoad", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppKeysMngrCertLoad(mngr, filename, format, type)); +} + + +xmlSecKeyPtr +xmlSecCryptoAppKeyLoad(const char *filename, xmlSecKeyDataFormat format, + const char *pwd, void* pwdCallback, void* pwdCallbackCtx) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoAppKeyLoad == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoAppKeyLoad", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppKeyLoad(filename, format, pwd, pwdCallback, pwdCallbackCtx)); +} + + +xmlSecKeyPtr +xmlSecCryptoAppPkcs12Load(const char* filename, const char* pwd, void* pwdCallback, + void* pwdCallbackCtx) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoAppPkcs12Load == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoAppPkcs12Load", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppPkcs12Load(filename, pwd, pwdCallback, pwdCallbackCtx)); +} + +int +xmlSecCryptoAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, xmlSecKeyDataFormat format) { + if((xmlSecCryptoDLGetFunctions() == NULL) || (xmlSecCryptoDLGetFunctions()->cryptoAppKeyCertLoad == NULL)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "cryptoAppKeyCertLoad", + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppKeyCertLoad(key, filename, format)); +} + +void* +xmlSecCryptoAppGetDefaultPwdCallback(void) { + if(xmlSecCryptoDLGetFunctions() == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_NOT_IMPLEMENTED, + XMLSEC_ERRORS_NO_MESSAGE); + return(NULL); + } + + return(xmlSecCryptoDLGetFunctions()->cryptoAppDefaultPwdCallback); +} + +#endif /* XMLSEC_NO_CRYPTO_DYNAMIC_LOADING */ + diff --git a/src/dl.c b/src/dl.c new file mode 100644 index 00000000..0e2c0981 --- /dev/null +++ b/src/dl.c @@ -0,0 +1,740 @@ +/** + * XML Security Library (http://www.aleksey.com/xmlsec). + * + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + */ +#include "globals.h" + + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <time.h> + +#include <libxml/tree.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/app.h> +#include <xmlsec/list.h> +#include <xmlsec/keysdata.h> +#include <xmlsec/keys.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/transforms.h> +#include <xmlsec/private.h> +#include <xmlsec/errors.h> +#include <xmlsec/dl.h> + +#ifndef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING + +#include "xmlsec-ltdl.h" + +#if defined(_MSC_VER) +#define snprintf _snprintf +#endif + +/*********************************************************************** + * + * loaded libraries list + * + **********************************************************************/ +typedef struct _xmlSecCryptoDLLibrary xmlSecCryptoDLLibrary, + *xmlSecCryptoDLLibraryPtr; +struct _xmlSecCryptoDLLibrary { + xmlChar* name; + xmlChar* filename; + xmlChar* getFunctionsName; + xmlSecCryptoDLFunctionsPtr functions; + xmlsec_lt_dlhandle handle; +}; + +static xmlSecCryptoDLLibraryPtr xmlSecCryptoDLLibraryCreate (const xmlChar* name); +static void xmlSecCryptoDLLibraryDestroy (xmlSecCryptoDLLibraryPtr lib); +static xmlSecCryptoDLLibraryPtr xmlSecCryptoDLLibraryDuplicate (xmlSecCryptoDLLibraryPtr lib); +static xmlChar* xmlSecCryptoDLLibraryConstructFilename (const xmlChar* name); +static xmlChar* xmlSecCryptoDLLibraryConstructGetFunctionsName(const xmlChar* name); + + +static xmlSecPtrListKlass xmlSecCryptoDLLibrariesListKlass = { + BAD_CAST "dl-libraries-list", + (xmlSecPtrDuplicateItemMethod)xmlSecCryptoDLLibraryDuplicate,/* xmlSecPtrDuplicateItemMethod duplicateItem; */ + (xmlSecPtrDestroyItemMethod)xmlSecCryptoDLLibraryDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */ + NULL, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */ + NULL, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */ +}; +static xmlSecPtrListId xmlSecCryptoDLLibrariesListGetKlass (void); +static int xmlSecCryptoDLLibrariesListFindByName (xmlSecPtrListPtr list, + const xmlChar* name); + +typedef xmlSecCryptoDLFunctionsPtr (*xmlSecCryptoGetFunctionsCallback)(void); + +static xmlSecCryptoDLLibraryPtr +xmlSecCryptoDLLibraryCreate(const xmlChar* name) { + xmlSecCryptoDLLibraryPtr lib; + xmlSecCryptoGetFunctionsCallback getFunctions; + + xmlSecAssert2(name != NULL, NULL); + + /* fprintf (stderr, "loading \"library %s\"...\n", name); */ + + /* Allocate a new xmlSecCryptoDLLibrary and fill the fields. */ + lib = (xmlSecCryptoDLLibraryPtr)xmlMalloc(sizeof(xmlSecCryptoDLLibrary)); + if(lib == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", sizeof(lib)); + return(NULL); + } + memset(lib, 0, sizeof(xmlSecCryptoDLLibrary)); + + lib->name = xmlStrdup(name); + if(lib->name == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + "xmlStrdup", + NULL, + XMLSEC_ERRORS_R_MALLOC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecCryptoDLLibraryDestroy(lib); + return(NULL); + } + + lib->filename = xmlSecCryptoDLLibraryConstructFilename(name); + if(lib->filename == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + "xmlSecCryptoDLLibraryConstructFilename", + NULL, + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecCryptoDLLibraryDestroy(lib); + return(NULL); + } + + lib->getFunctionsName = xmlSecCryptoDLLibraryConstructGetFunctionsName(name); + if(lib->getFunctionsName == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + "xmlSecCryptoDLLibraryConstructGetFunctionsName", + NULL, + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecCryptoDLLibraryDestroy(lib); + return(NULL); + } + + lib->handle = xmlsec_lt_dlopen((char*)lib->filename); + if(lib->handle == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + "xmlsec_lt_dlopen", + NULL, + XMLSEC_ERRORS_R_IO_FAILED, + "filename=%s", + xmlSecErrorsSafeString(lib->filename)); + xmlSecCryptoDLLibraryDestroy(lib); + return(NULL); + } + + getFunctions = (xmlSecCryptoGetFunctionsCallback)xmlsec_lt_dlsym(lib->handle, (char*)lib->getFunctionsName); + if(getFunctions == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + "xmlsec_lt_dlsym", + NULL, + XMLSEC_ERRORS_R_IO_FAILED, + "function=%s", + xmlSecErrorsSafeString(lib->getFunctionsName)); + xmlSecCryptoDLLibraryDestroy(lib); + return(NULL); + } + + if(getFunctions == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "invalid configuration: no way to load library"); + xmlSecCryptoDLLibraryDestroy(lib); + return(NULL); + } + + lib->functions = getFunctions(); + if(lib->functions == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + "getFunctions", + NULL, + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecCryptoDLLibraryDestroy(lib); + return(NULL); + } + + /* fprintf (stderr, "library %s loaded\n", name); */ + return(lib); +} + +static void +xmlSecCryptoDLLibraryDestroy(xmlSecCryptoDLLibraryPtr lib) { + xmlSecAssert(lib != NULL); + + fprintf (stderr, "unloading \"library %s\"...\n", lib->name); + if(lib->name != NULL) { + xmlFree(lib->name); + } + + if(lib->filename != NULL) { + xmlFree(lib->filename); + } + + if(lib->getFunctionsName != NULL) { + xmlFree(lib->getFunctionsName); + } + + if(lib->handle != NULL) { + int ret; + + ret = xmlsec_lt_dlclose(lib->handle); + if(ret != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + "xmlsec_lt_dlclose", + NULL, + XMLSEC_ERRORS_R_IO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + } + } + + memset(lib, 0, sizeof(xmlSecCryptoDLLibrary)); + xmlFree(lib); +} + +static xmlSecCryptoDLLibraryPtr +xmlSecCryptoDLLibraryDuplicate(xmlSecCryptoDLLibraryPtr lib) { + xmlSecAssert2(lib != NULL, NULL); + xmlSecAssert2(lib->name != NULL, NULL); + + return(xmlSecCryptoDLLibraryCreate(lib->name)); +} + +static xmlChar* +xmlSecCryptoDLLibraryConstructFilename(const xmlChar* name) { + static xmlChar tmpl[] = "lib%s-%s.so"; + xmlChar* res; + int len; + + xmlSecAssert2(name != NULL, NULL); + + /* TODO */ + len = xmlStrlen(BAD_CAST PACKAGE) + xmlStrlen(name) + xmlStrlen(tmpl) + 1; + res = (xmlChar*)xmlMalloc(len + 1); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", len + 1); + return(NULL); + } + snprintf(res, len, tmpl, PACKAGE, name); + + return(res); +} + +static xmlChar* +xmlSecCryptoDLLibraryConstructGetFunctionsName(const xmlChar* name) { + static xmlChar tmpl[] = "xmlSecCryptoGetFunctions_%s"; + xmlChar* res; + int len; + + xmlSecAssert2(name != NULL, NULL); + + len = xmlStrlen(name) + xmlStrlen(tmpl) + 1; + res = (xmlChar*)xmlMalloc(len + 1); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", len + 1); + return(NULL); + } + snprintf(res, len, tmpl, name); + + return(res); +} + +static xmlSecPtrListId +xmlSecCryptoDLLibrariesListGetKlass(void) { + return(&xmlSecCryptoDLLibrariesListKlass); +} + +static int +xmlSecCryptoDLLibrariesListFindByName(xmlSecPtrListPtr list, const xmlChar* name) { + xmlSecSize i, size; + xmlSecCryptoDLLibraryPtr lib; + + xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecCryptoDLLibrariesListGetKlass()), -1); + xmlSecAssert2(name != NULL, -1); + + size = xmlSecPtrListGetSize(list); + for(i = 0; i < size; ++i) { + lib = (xmlSecCryptoDLLibraryPtr)xmlSecPtrListGetItem(list, i); + if((lib != NULL) && (lib->name != NULL) && (xmlStrcmp(lib->name, name) == 0)) { + return(i); + } + } + return(-1); +} + +/****************************************************************************** + * + * Dynamic load functions + * + *****************************************************************************/ +static xmlSecCryptoDLFunctionsPtr gXmlSecCryptoDLFunctions = NULL; +static xmlSecPtrList gXmlSecCryptoDLLibraries; + +int +xmlSecCryptoDLInit(void) { + int ret; + + ret = xmlSecPtrListInitialize(&gXmlSecCryptoDLLibraries, xmlSecCryptoDLLibrariesListGetKlass()); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecPtrListPtrInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "xmlSecCryptoDLLibrariesListGetKlass"); + return(-1); + } + + ret = xmlsec_lt_dlinit (); + if(ret != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlsec_lt_dlinit", + XMLSEC_ERRORS_R_IO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + /* TODO: LTDL_SET_PRELOADED_SYMBOLS(); */ + return(0); +} + +int +xmlSecCryptoDLShutdown(void) { + int ret; + + xmlSecPtrListFinalize(&gXmlSecCryptoDLLibraries); + + ret = xmlsec_lt_dlexit (); + if(ret != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlsec_lt_dlexit", + XMLSEC_ERRORS_R_IO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + } + return(0); +} + +/** + * xmlSecCryptoDLLoadLibrary: + * @crypto: the desired crypto library name ("openssl", "nss", ...). + * + * Loads the xmlsec-<crypto> library. This function is NOT thread safe, + * application MUST NOT call #xmlSecCryptoDLLoadLibrary, #xmlSecCryptoDLGetLibraryFunctions, + * and #xmlSecCryptoDLUnloadLibrary functions from multiple threads. + * + * Returns 0 on success or a negative value if an error occurs. + */ +int +xmlSecCryptoDLLoadLibrary(const xmlChar* crypto) { + xmlSecCryptoDLFunctionsPtr functions; + int ret; + + xmlSecAssert2(crypto != NULL, -1); + + functions = xmlSecCryptoDLGetLibraryFunctions(crypto); + if(functions == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoDLGetLibraryFunctions", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecCryptoDLSetFunctions(functions); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoDLSetFunctions", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + return(0); +} + +/** + * xmlSecCryptoDLGetLibraryFunctions: + * @crypto: the desired crypto library name ("openssl", "nss", ...). + * + * Loads the xmlsec-<crypto> library and gets global crypto functions/transforms/keys data/keys store + * table. This function is NOT thread safe, application MUST NOT call #xmlSecCryptoDLLoadLibrary, + * #xmlSecCryptoDLGetLibraryFunctions, and #xmlSecCryptoDLUnloadLibrary functions from multiple threads. + * + * Returns the table or NULL if an error occurs. + */ +xmlSecCryptoDLFunctionsPtr +xmlSecCryptoDLGetLibraryFunctions(const xmlChar* crypto) { + xmlSecCryptoDLLibraryPtr lib; + int pos; + int ret; + + xmlSecAssert2(crypto != NULL, NULL); + + pos = xmlSecCryptoDLLibrariesListFindByName(&gXmlSecCryptoDLLibraries, crypto); + if(pos >= 0) { + lib = (xmlSecCryptoDLLibraryPtr)xmlSecPtrListGetItem(&gXmlSecCryptoDLLibraries, pos); + xmlSecAssert2(lib != NULL, NULL); + xmlSecAssert2(lib->functions != NULL, NULL); + + return(lib->functions); + } + + lib = xmlSecCryptoDLLibraryCreate(crypto); + if(lib == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoDLLibraryCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "crypto=%s", + xmlSecErrorsSafeString(crypto)); + return(NULL); + } + + ret = xmlSecPtrListAdd(&gXmlSecCryptoDLLibraries, lib); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecPtrListAdd", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "crypto=%s", + xmlSecErrorsSafeString(crypto)); + xmlSecCryptoDLLibraryDestroy(lib); + return(NULL); + } + + return(lib->functions); +} + +/** + * xmlSecCryptoDLUnloadLibrary: + * @crypto: the desired crypto library name ("openssl", "nss", ...). + * + * Unloads the xmlsec-<crypto> library. All pointers to this library + * functions tables became invalid. This function is NOT thread safe, + * application MUST NOT call #xmlSecCryptoDLLoadLibrary, #xmlSecCryptoDLGetLibraryFunctions, + * and #xmlSecCryptoDLUnloadLibrary functions from multiple threads. + * + * Returns 0 on success or a negative value if an error occurs. + */ +int +xmlSecCryptoDLUnloadLibrary(const xmlChar* crypto) { + xmlSecCryptoDLLibraryPtr lib; + int pos; + int ret; + + xmlSecAssert2(crypto != NULL, -1); + + pos = xmlSecCryptoDLLibrariesListFindByName(&gXmlSecCryptoDLLibraries, crypto); + if(pos < 0) { + /* todo: is it an error? */ + return(0); + } + + lib = (xmlSecCryptoDLLibraryPtr)xmlSecPtrListGetItem(&gXmlSecCryptoDLLibraries, pos); + if((lib != NULL) && (lib->functions == gXmlSecCryptoDLFunctions)) { + gXmlSecCryptoDLFunctions = NULL; + } + + ret = xmlSecPtrListRemove(&gXmlSecCryptoDLLibraries, pos); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecPtrListRemove", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(0); +} + +/** + * xmlSecCryptoDLSetFunctions: + * @functions: the new table + * + * Sets global crypto functions/transforms/keys data/keys store table. + * + * Returns 0 on success or a negative value if an error occurs. + */ +int +xmlSecCryptoDLSetFunctions(xmlSecCryptoDLFunctionsPtr functions) { + xmlSecAssert2(functions != NULL, -1); + + gXmlSecCryptoDLFunctions = functions; + + return(0); +} + +/** + * xmlSecCryptoDLGetFunctions: + * + * Gets global crypto functions/transforms/keys data/keys store table. + * + * Returns the table. + */ +xmlSecCryptoDLFunctionsPtr +xmlSecCryptoDLGetFunctions(void) { + return(gXmlSecCryptoDLFunctions); +} + +#endif /* XMLSEC_NO_CRYPTO_DYNAMIC_LOADING */ + +/** + * xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms: + * @functions: the functions table. + * + * Registers the key data and transforms klasses from @functions table in xmlsec. + * + * Returns 0 on success or a negative value if an error occurs. + */ +int +xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms(struct _xmlSecCryptoDLFunctions* functions) { + xmlSecAssert2(functions != NULL, -1); + + /** + * Register keys + */ + if((functions->keyDataAesGetKlass != NULL) && (xmlSecKeyDataIdsRegister(functions->keyDataAesGetKlass()) < 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(functions->keyDataAesGetKlass())), + "xmlSecKeyDataIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + if((functions->keyDataDesGetKlass != NULL) && (xmlSecKeyDataIdsRegister(functions->keyDataDesGetKlass()) < 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(functions->keyDataDesGetKlass())), + "xmlSecKeyDataIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + if((functions->keyDataDsaGetKlass != NULL) && (xmlSecKeyDataIdsRegister(functions->keyDataDsaGetKlass()) < 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(functions->keyDataDsaGetKlass())), + "xmlSecKeyDataIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + if((functions->keyDataHmacGetKlass != NULL) && (xmlSecKeyDataIdsRegister(functions->keyDataHmacGetKlass()) < 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(functions->keyDataHmacGetKlass())), + "xmlSecKeyDataIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + if((functions->keyDataRsaGetKlass != NULL) && (xmlSecKeyDataIdsRegister(functions->keyDataRsaGetKlass()) < 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(functions->keyDataRsaGetKlass())), + "xmlSecKeyDataIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + if((functions->keyDataX509GetKlass != NULL) && (xmlSecKeyDataIdsRegister(functions->keyDataX509GetKlass()) < 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(functions->keyDataX509GetKlass())), + "xmlSecKeyDataIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + if((functions->keyDataRawX509CertGetKlass != NULL) && (xmlSecKeyDataIdsRegister(functions->keyDataRawX509CertGetKlass()) < 0)) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(functions->keyDataRawX509CertGetKlass())), + "xmlSecKeyDataIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + + /** + * Register transforms + */ + if((functions->transformAes128CbcGetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformAes128CbcGetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformAes128CbcGetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformAes192CbcGetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformAes192CbcGetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformAes192CbcGetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformAes256CbcGetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformAes256CbcGetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformAes256CbcGetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformKWAes128GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformKWAes128GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformKWAes128GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformKWAes192GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformKWAes192GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformKWAes192GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformKWAes256GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformKWAes256GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformKWAes256GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformDes3CbcGetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformDes3CbcGetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformDes3CbcGetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformKWDes3GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformKWDes3GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformKWDes3GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformDsaSha1GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformDsaSha1GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformDsaSha1GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformHmacSha1GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformHmacSha1GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformHmacSha1GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformHmacRipemd160GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformHmacRipemd160GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformHmacRipemd160GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformHmacMd5GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformHmacMd5GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformHmacMd5GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformRipemd160GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformRipemd160GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformRipemd160GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformRsaSha1GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformRsaSha1GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformRsaSha1GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformRsaPkcs1GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformRsaPkcs1GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformRsaPkcs1GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformRsaOaepGetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformRsaOaepGetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformRsaOaepGetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + if((functions->transformSha1GetKlass != NULL) && xmlSecTransformIdsRegister(functions->transformSha1GetKlass()) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + xmlSecErrorsSafeString(xmlSecTransformKlassGetName(functions->transformSha1GetKlass())), + "xmlSecTransformIdsRegister", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + return(0); +} + + diff --git a/src/errors.c b/src/errors.c index 04f2a2a9..302a33fd 100644 --- a/src/errors.c +++ b/src/errors.c @@ -22,6 +22,10 @@ #define XMLSEC_ERRORS_BUFFER_SIZE 1024 +#if defined(_MSC_VER) +#define snprintf _snprintf +#endif + typedef struct _xmlSecErrorDescription xmlSecErrorDescription, *xmlSecErrorDescriptionPtr; struct _xmlSecErrorDescription { int errorCode; diff --git a/src/globals.h b/src/globals.h index 158c125e..35a238cc 100644 --- a/src/globals.h +++ b/src/globals.h @@ -12,8 +12,14 @@ #ifndef __XMLSEC_GLOBALS_H__ #define __XMLSEC_GLOBALS_H__ +/** + * Use autoconf defines if present. + */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif /* HAVE_CONFIG_H */ #define IN_XMLSEC +#define XMLSEC_PRIVATE #endif /* __XMLSEC_GLOBALS_H__ */ diff --git a/src/gnutls/Makefile.am b/src/gnutls/Makefile.am index 4c35615b..b2dd9577 100644 --- a/src/gnutls/Makefile.am +++ b/src/gnutls/Makefile.am @@ -5,6 +5,7 @@ EXTRA_DIST = \ $(NULL) INCLUDES = \ + -DPACKAGE=\"@PACKAGE@\" \ -I$(top_srcdir) \ -I$(top_srcdir)/include \ $(XMLSEC_DEFINES) \ diff --git a/src/gnutls/app.c b/src/gnutls/app.c index 04d7d7be..543c924a 100644 --- a/src/gnutls/app.c +++ b/src/gnutls/app.c @@ -184,30 +184,6 @@ xmlSecGnuTLSAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, const char *filename, return(-1); } -/** - * xmlSecGnuTLSAppKeysMngrAddCertsPath: - * @mngr: the keys manager. - * @path: the path to trusted certificates. - * - * Reads cert from @path and adds to the list of trusted certificates - * (not implemented yet). - * - * Returns 0 on success or a negative value otherwise. - */ -int -xmlSecGnuTLSAppKeysMngrAddCertsPath(xmlSecKeysMngrPtr mngr, const char *path) { - xmlSecAssert2(mngr != NULL, -1); - xmlSecAssert2(path != NULL, -1); - - /* TODO */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSAppKeysMngrAddCertsPath", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); -} - #endif /* XMLSEC_NO_X509 */ /** @@ -390,3 +366,15 @@ xmlSecGnuTLSAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filename, return(0); } +/** + * xmlSecGnuTLSAppGetDefaultPwdCallback: + * + * Gets default password callback. + * + * Returns default password callback. + */ +void* +xmlSecGnuTLSAppGetDefaultPwdCallback(void) { + return(NULL); +} + diff --git a/src/gnutls/crypto.c b/src/gnutls/crypto.c index e2d568bf..0de2d6ae 100644 --- a/src/gnutls/crypto.c +++ b/src/gnutls/crypto.c @@ -17,11 +17,94 @@ #include <xmlsec/keys.h> #include <xmlsec/transforms.h> #include <xmlsec/errors.h> +#include <xmlsec/dl.h> +#include <xmlsec/private.h> +#include <xmlsec/gnutls/app.h> #include <xmlsec/gnutls/crypto.h> -static int xmlSecGnuTLSKeysInit (void); -static int xmlSecGnuTLSTransformsInit (void); +static xmlSecCryptoDLFunctionsPtr gXmlSecGnuTLSFunctions = NULL; + +xmlSecCryptoDLFunctionsPtr +xmlSecCryptoGetFunctions_gnutls(void) { + static xmlSecCryptoDLFunctions functions; + + if(gXmlSecGnuTLSFunctions != NULL) { + return(gXmlSecGnuTLSFunctions); + } + + memset(&functions, 0, sizeof(functions)); + gXmlSecGnuTLSFunctions = &functions; + + /** + * Crypto Init/shutdown + */ + gXmlSecGnuTLSFunctions->cryptoInit = xmlSecGnuTLSInit; + gXmlSecGnuTLSFunctions->cryptoShutdown = xmlSecGnuTLSShutdown; + gXmlSecGnuTLSFunctions->cryptoKeysMngrInit = xmlSecGnuTLSKeysMngrInit; + + /** + * Key data ids + */ +#ifndef XMLSEC_NO_AES + gXmlSecGnuTLSFunctions->keyDataAesGetKlass = xmlSecGnuTLSKeyDataAesGetKlass; +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES + gXmlSecGnuTLSFunctions->keyDataDesGetKlass = xmlSecGnuTLSKeyDataDesGetKlass; +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_HMAC + gXmlSecGnuTLSFunctions->keyDataHmacGetKlass = xmlSecGnuTLSKeyDataHmacGetKlass; +#endif /* XMLSEC_NO_HMAC */ + + /** + * Key data store ids + */ + + /** + * Crypto transforms ids + */ +#ifndef XMLSEC_NO_AES + gXmlSecGnuTLSFunctions->transformAes128CbcGetKlass = xmlSecGnuTLSTransformAes128CbcGetKlass; + gXmlSecGnuTLSFunctions->transformAes192CbcGetKlass = xmlSecGnuTLSTransformAes192CbcGetKlass; + gXmlSecGnuTLSFunctions->transformAes256CbcGetKlass = xmlSecGnuTLSTransformAes256CbcGetKlass; +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES + gXmlSecGnuTLSFunctions->transformDes3CbcGetKlass = xmlSecGnuTLSTransformDes3CbcGetKlass; +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_HMAC + gXmlSecGnuTLSFunctions->transformHmacSha1GetKlass = xmlSecGnuTLSTransformHmacSha1GetKlass; + gXmlSecGnuTLSFunctions->transformHmacRipemd160GetKlass = xmlSecGnuTLSTransformHmacRipemd160GetKlass; + gXmlSecGnuTLSFunctions->transformHmacMd5GetKlass = xmlSecGnuTLSTransformHmacMd5GetKlass; +#endif /* XMLSEC_NO_HMAC */ + +#ifndef XMLSEC_NO_SHA1 + gXmlSecGnuTLSFunctions->transformSha1GetKlass = xmlSecGnuTLSTransformSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + + /** + * High level routines form xmlsec command line utility + */ + gXmlSecGnuTLSFunctions->cryptoAppInit = xmlSecGnuTLSAppInit; + gXmlSecGnuTLSFunctions->cryptoAppShutdown = xmlSecGnuTLSAppShutdown; + gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrInit = xmlSecGnuTLSAppDefaultKeysMngrInit; + gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrAdoptKey = xmlSecGnuTLSAppDefaultKeysMngrAdoptKey; + gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrLoad = xmlSecGnuTLSAppDefaultKeysMngrLoad; + gXmlSecGnuTLSFunctions->cryptoAppDefaultKeysMngrSave = xmlSecGnuTLSAppDefaultKeysMngrSave; +#ifndef XMLSEC_NO_X509 + gXmlSecGnuTLSFunctions->cryptoAppKeysMngrCertLoad = xmlSecGnuTLSAppKeysMngrCertLoad; + gXmlSecGnuTLSFunctions->cryptoAppPkcs12Load = xmlSecGnuTLSAppPkcs12Load; + gXmlSecGnuTLSFunctions->cryptoAppKeyCertLoad = xmlSecGnuTLSAppKeyCertLoad; +#endif /* XMLSEC_NO_X509 */ + gXmlSecGnuTLSFunctions->cryptoAppKeyLoad = xmlSecGnuTLSAppKeyLoad; + gXmlSecGnuTLSFunctions->cryptoAppDefaultPwdCallback = (void*)xmlSecGnuTLSAppGetDefaultPwdCallback; + + return(gXmlSecGnuTLSFunctions); +} + /** * xmlSecGnuTLSInit: @@ -32,18 +115,10 @@ static int xmlSecGnuTLSTransformsInit (void); */ int xmlSecGnuTLSInit (void) { - if(xmlSecGnuTLSKeysInit() < 0) { + if(xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms(xmlSecCryptoGetFunctions_gnutls()) < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, - "xmlSecGnuTLSKeysInit", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecGnuTLSTransformsInit() < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecGnuTLSTransformsInit", + "xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); @@ -110,126 +185,3 @@ xmlSecGnuTLSGenerateRandom(xmlSecBufferPtr buffer, xmlSecSize size) { gcry_randomize(xmlSecBufferGetData(buffer), size, GCRY_STRONG_RANDOM); return(0); } - - -static int -xmlSecGnuTLSKeysInit(void) { - -#ifndef XMLSEC_NO_AES - if(xmlSecKeyDataIdsRegister(xmlSecGnuTLSKeyDataAesId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecGnuTLSKeyDataAesId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_AES */ - -#ifndef XMLSEC_NO_DES - if(xmlSecKeyDataIdsRegister(xmlSecGnuTLSKeyDataDesId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecGnuTLSKeyDataDesId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_DES */ - -#ifndef XMLSEC_NO_HMAC - if(xmlSecKeyDataIdsRegister(xmlSecGnuTLSKeyDataHmacId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecGnuTLSKeyDataHmacId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_HMAC */ - - return(0); -} - -static int -xmlSecGnuTLSTransformsInit(void) { - -#ifndef XMLSEC_NO_HMAC - if(xmlSecTransformIdsRegister(xmlSecGnuTLSTransformHmacSha1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecGnuTLSTransformHmacSha1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecGnuTLSTransformHmacRipemd160Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecGnuTLSTransformHmacRipemd160Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecGnuTLSTransformHmacMd5Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecGnuTLSTransformHmacMd5Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_HMAC */ - -#ifndef XMLSEC_NO_SHA1 - if(xmlSecTransformIdsRegister(xmlSecGnuTLSTransformSha1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecGnuTLSTransformSha1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_SHA1 */ - -#ifndef XMLSEC_NO_DES - if(xmlSecTransformIdsRegister(xmlSecGnuTLSTransformDes3CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecGnuTLSTransformDes3CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_DES */ - -#ifndef XMLSEC_NO_AES - if(xmlSecTransformIdsRegister(xmlSecGnuTLSTransformAes128CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecGnuTLSTransformAes128CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecGnuTLSTransformAes192CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecGnuTLSTransformAes192CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecGnuTLSTransformAes256CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecGnuTLSTransformAes256CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_AES */ - - return(0); -} - diff --git a/src/gnutls/globals.h b/src/gnutls/globals.h index 0f2bf445..272a27b8 100644 --- a/src/gnutls/globals.h +++ b/src/gnutls/globals.h @@ -11,8 +11,14 @@ #ifndef __XMLSEC_GLOBALS_H__ #define __XMLSEC_GLOBALS_H__ +/** + * Use autoconf defines if present. + */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif /* HAVE_CONFIG_H */ #define IN_XMLSEC_CRYPTO +#define XMLSEC_PRIVATE #endif /* ! __XMLSEC_GLOBALS_H__ */ diff --git a/src/ltdl.c b/src/ltdl.c new file mode 100644 index 00000000..820bd307 --- /dev/null +++ b/src/ltdl.c @@ -0,0 +1,3999 @@ +/* ltdl.c -- system independent dlopen wrapper + Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + Originally by Thomas Tanner <tanner@ffii.org> + This file is part of GNU Libtool. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU libtool, you may include it under the same +distribution terms that you use for the rest of that program. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA + +*/ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#if HAVE_UNISTD_H +# include <unistd.h> +#endif + +#if HAVE_STDIO_H +# include <stdio.h> +#endif + +#if HAVE_STDLIB_H +# include <stdlib.h> +#endif + +#if HAVE_STRING_H +# include <string.h> +#else +# if HAVE_STRINGS_H +# include <strings.h> +# endif +#endif + +#if HAVE_CTYPE_H +# include <ctype.h> +#endif + +#if HAVE_MALLOC_H +# include <malloc.h> +#endif + +#if HAVE_MEMORY_H +# include <memory.h> +#endif + +#if HAVE_ERRNO_H +# include <errno.h> +#endif + +#if HAVE_DIRENT_H +# include <dirent.h> +# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) +#else +# define dirent direct +# define LT_D_NAMLEN(dirent) ((dirent)->d_namlen) +# if HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif +# if HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif +# if HAVE_NDIR_H +# include <ndir.h> +# endif +#endif + +#if HAVE_ARGZ_H +# include <argz.h> +#endif + +#if HAVE_ASSERT_H +# include <assert.h> +#else +# define assert(arg) ((void) 0) +#endif + +#include "ltdl.h" + +#if WITH_DMALLOC +# include <dmalloc.h> +#endif + + + + +/* --- WINDOWS SUPPORT --- */ + + +#ifdef DLL_EXPORT +# define LT_GLOBAL_DATA __declspec(dllexport) +#else +# define LT_GLOBAL_DATA +#endif + +/* fopen() mode flags for reading a text file */ +#undef LT_READTEXT_MODE +#ifdef __WINDOWS__ +# define LT_READTEXT_MODE "rt" +#else +# define LT_READTEXT_MODE "r" +#endif + + + + +/* --- MANIFEST CONSTANTS --- */ + + +/* Standard libltdl search path environment variable name */ +#undef LTDL_SEARCHPATH_VAR +#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" + +/* Standard libtool archive file extension. */ +#undef LTDL_ARCHIVE_EXT +#define LTDL_ARCHIVE_EXT ".la" + +/* max. filename length */ +#ifndef LT_FILENAME_MAX +# define LT_FILENAME_MAX 1024 +#endif + +/* This is the maximum symbol size that won't require malloc/free */ +#undef LT_SYMBOL_LENGTH +#define LT_SYMBOL_LENGTH 128 + +/* This accounts for the _LTX_ separator */ +#undef LT_SYMBOL_OVERHEAD +#define LT_SYMBOL_OVERHEAD 5 + + + + +/* --- MEMORY HANDLING --- */ + + +/* These are the functions used internally. In addition to making + use of the associated function pointers above, they also perform + error handling. */ +static char *lt_estrdup LT_PARAMS((const char *str)); +static lt_ptr lt_emalloc LT_PARAMS((size_t size)); +static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size)); + +static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); + +/* These are the pointers that can be changed by the caller: */ +LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)) + = (lt_ptr (*) LT_PARAMS((size_t))) malloc; +LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size)) + = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc; +LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)) + = (void (*) LT_PARAMS((lt_ptr))) free; + +/* The following macros reduce the amount of typing needed to cast + assigned memory. */ +#if WITH_DMALLOC + +#define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) +#define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) +#define LT_DLFREE(p) \ + LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END + +#define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) + +#else + +#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp))) +#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp))) +#define LT_DLFREE(p) \ + LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END + +#define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp))) + +#endif + +#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \ + if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \ + } LT_STMT_END + + +/* --- REPLACEMENT FUNCTIONS --- */ + + +#undef strdup +#define strdup rpl_strdup + +static char *strdup LT_PARAMS((const char *str)); + +static char * +strdup(str) + const char *str; +{ + char *tmp = NULL; + + if (str) + { + tmp = LT_DLMALLOC (char, 1+ strlen (str)); + if (tmp) + { + strcpy(tmp, str); + } + } + + return tmp; +} + + +#if ! HAVE_STRCMP + +#undef strcmp +#define strcmp rpl_strcmp + +static int strcmp LT_PARAMS((const char *str1, const char *str2)); + +static int +strcmp (str1, str2) + const char *str1; + const char *str2; +{ + if (str1 == str2) + return 0; + if (str1 == NULL) + return -1; + if (str2 == NULL) + return 1; + + for (;*str1 && *str2; ++str1, ++str2) + { + if (*str1 != *str2) + break; + } + + return (int)(*str1 - *str2); +} +#endif + + +#if ! HAVE_STRCHR + +# if HAVE_INDEX +# define strchr index +# else +# define strchr rpl_strchr + +static const char *strchr LT_PARAMS((const char *str, int ch)); + +static const char* +strchr(str, ch) + const char *str; + int ch; +{ + const char *p; + + for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p) + /*NOWORK*/; + + return (*p == (char)ch) ? p : 0; +} + +# endif +#endif /* !HAVE_STRCHR */ + + +#if ! HAVE_STRRCHR + +# if HAVE_RINDEX +# define strrchr rindex +# else +# define strrchr rpl_strrchr + +static const char *strrchr LT_PARAMS((const char *str, int ch)); + +static const char* +strrchr(str, ch) + const char *str; + int ch; +{ + const char *p, *q = NULL; + + for (p = str; *p != LT_EOS_CHAR; ++p) + { + if (*p == (char) ch) + { + q = p; + } + } + + return q; +} + +# endif +#endif + +/* NOTE: Neither bcopy nor the memcpy implementation below can + reliably handle copying in overlapping areas of memory. Use + memmove (for which there is a fallback implmentation below) + if you need that behaviour. */ +#if ! HAVE_MEMCPY + +# if HAVE_BCOPY +# define memcpy(dest, src, size) bcopy (src, dest, size) +# else +# define memcpy rpl_memcpy + +static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); + +static lt_ptr +memcpy (dest, src, size) + lt_ptr dest; + const lt_ptr src; + size_t size; +{ + size_t i = 0; + + for (i = 0; i < size; ++i) + { + dest[i] = src[i]; + } + + return dest; +} + +# endif /* !HAVE_BCOPY */ +#endif /* !HAVE_MEMCPY */ + +#if ! HAVE_MEMMOVE +# define memmove rpl_memmove + +static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); + +static lt_ptr +memmove (dest, src, size) + lt_ptr dest; + const lt_ptr src; + size_t size; +{ + size_t i; + + if (dest < src) + for (i = 0; i < size; ++i) + { + dest[i] = src[i]; + } + else if (dest > src) + for (i = size -1; i >= 0; --i) + { + dest[i] = src[i]; + } + + return dest; +} + +#endif /* !HAVE_MEMMOVE */ + + +/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>, + ``realloc is not entirely portable'' + In any case we want to use the allocator supplied by the user without + burdening them with an lt_dlrealloc function pointer to maintain. + Instead implement our own version (with known boundary conditions) + using lt_dlmalloc and lt_dlfree. */ + +#undef realloc +#define realloc rpl_realloc + +static lt_ptr +realloc (ptr, size) + lt_ptr ptr; + size_t size; +{ + if (size == 0) + { + /* For zero or less bytes, free the original memory */ + if (ptr != NULL) + { + lt_dlfree (ptr); + } + + return (lt_ptr) 0; + } + else if (ptr == NULL) + { + /* Allow reallocation of a NULL pointer. */ + return lt_dlmalloc (size); + } + else + { + /* Allocate a new block, copy and free the old block. */ + lt_ptr mem = lt_dlmalloc (size); + + if (mem) + { + memcpy (mem, ptr, size); + lt_dlfree (ptr); + } + + /* Note that the contents of PTR are not damaged if there is + insufficient memory to realloc. */ + return mem; + } +} + + +#if ! HAVE_ARGZ_APPEND +# define argz_append rpl_argz_append + +static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len, + const char *buf, size_t buf_len)); + +static error_t +argz_append (pargz, pargz_len, buf, buf_len) + char **pargz; + size_t *pargz_len; + const char *buf; + size_t buf_len; +{ + size_t argz_len; + char *argz; + + assert (pargz); + assert (pargz_len); + assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); + + /* If nothing needs to be appended, no more work is required. */ + if (buf_len == 0) + return 0; + + /* Ensure there is enough room to append BUF_LEN. */ + argz_len = *pargz_len + buf_len; + argz = LT_DLREALLOC (char, *pargz, argz_len); + if (!argz) + return ENOMEM; + + /* Copy characters from BUF after terminating '\0' in ARGZ. */ + memcpy (argz + *pargz_len, buf, buf_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} +#endif /* !HAVE_ARGZ_APPEND */ + + +#if ! HAVE_ARGZ_CREATE_SEP +# define argz_create_sep rpl_argz_create_sep + +static error_t argz_create_sep LT_PARAMS((const char *str, int delim, + char **pargz, size_t *pargz_len)); + +static error_t +argz_create_sep (str, delim, pargz, pargz_len) + const char *str; + int delim; + char **pargz; + size_t *pargz_len; +{ + size_t argz_len; + char *argz = NULL; + + assert (str); + assert (pargz); + assert (pargz_len); + + /* Make a copy of STR, but replacing each occurence of + DELIM with '\0'. */ + argz_len = 1+ LT_STRLEN (str); + if (argz_len) + { + const char *p; + char *q; + + argz = LT_DLMALLOC (char, argz_len); + if (!argz) + return ENOMEM; + + for (p = str, q = argz; *p != LT_EOS_CHAR; ++p) + { + if (*p == delim) + { + /* Ignore leading delimiters, and fold consecutive + delimiters in STR into a single '\0' in ARGZ. */ + if ((q > argz) && (q[-1] != LT_EOS_CHAR)) + *q++ = LT_EOS_CHAR; + else + --argz_len; + } + else + *q++ = *p; + } + /* Copy terminating LT_EOS_CHAR. */ + *q = *p; + } + + /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ + if (!argz_len) + LT_DLFREE (argz); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} +#endif /* !HAVE_ARGZ_CREATE_SEP */ + + +#if ! HAVE_ARGZ_INSERT +# define argz_insert rpl_argz_insert + +static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len, + char *before, const char *entry)); + +static error_t +argz_insert (pargz, pargz_len, before, entry) + char **pargz; + size_t *pargz_len; + char *before; + const char *entry; +{ + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + /* No BEFORE address indicates ENTRY should be inserted after the + current last element. */ + if (!before) + return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry)); + + /* This probably indicates a programmer error, but to preserve + semantics, scan back to the start of an entry if BEFORE points + into the middle of it. */ + while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR)) + --before; + + { + size_t entry_len = 1+ LT_STRLEN (entry); + size_t argz_len = *pargz_len + entry_len; + size_t offset = before - *pargz; + char *argz = LT_DLREALLOC (char, *pargz, argz_len); + + if (!argz) + return ENOMEM; + + /* Make BEFORE point to the equivalent offset in ARGZ that it + used to have in *PARGZ incase realloc() moved the block. */ + before = argz + offset; + + /* Move the ARGZ entries starting at BEFORE up into the new + space at the end -- making room to copy ENTRY into the + resulting gap. */ + memmove (before + entry_len, before, *pargz_len - offset); + memcpy (before, entry, entry_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + } + + return 0; +} +#endif /* !HAVE_ARGZ_INSERT */ + + +#if ! HAVE_ARGZ_NEXT +# define argz_next rpl_argz_next + +static char *argz_next LT_PARAMS((char *argz, size_t argz_len, + const char *entry)); + +static char * +argz_next (argz, argz_len, entry) + char *argz; + size_t argz_len; + const char *entry; +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (entry) + { + /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address + within the ARGZ vector. */ + assert ((!argz && !argz_len) + || ((argz <= entry) && (entry < (argz + argz_len)))); + + /* Move to the char immediately after the terminating + '\0' of ENTRY. */ + entry = 1+ strchr (entry, LT_EOS_CHAR); + + /* Return either the new ENTRY, or else NULL if ARGZ is + exhausted. */ + return (entry >= argz + argz_len) ? 0 : (char *) entry; + } + else + { + /* This should probably be flagged as a programmer error, + since starting an argz_next loop with the iterator set + to ARGZ is safer. To preserve semantics, handle the NULL + case by returning the start of ARGZ (if any). */ + if (argz_len > 0) + return argz; + else + return 0; + } +} +#endif /* !HAVE_ARGZ_NEXT */ + + + +#if ! HAVE_ARGZ_STRINGIFY +# define argz_stringify rpl_argz_stringify + +static void argz_stringify LT_PARAMS((char *argz, size_t argz_len, + int sep)); + +static void +argz_stringify (argz, argz_len, sep) + char *argz; + size_t argz_len; + int sep; +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (sep) + { + --argz_len; /* don't stringify the terminating EOS */ + while (--argz_len > 0) + { + if (argz[argz_len] == LT_EOS_CHAR) + argz[argz_len] = sep; + } + } +} +#endif /* !HAVE_ARGZ_STRINGIFY */ + + + + +/* --- TYPE DEFINITIONS -- */ + + +/* This type is used for the array of caller data sets in each handler. */ +typedef struct { + lt_dlcaller_id key; + lt_ptr data; +} lt_caller_data; + + + + +/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */ + + +/* Extract the diagnostic strings from the error table macro in the same + order as the enumerated indices in ltdl.h. */ + +static const char *lt_dlerror_strings[] = + { +#define LT_ERROR(name, diagnostic) (diagnostic), + lt_dlerror_table +#undef LT_ERROR + + 0 + }; + +/* This structure is used for the list of registered loaders. */ +struct lt_dlloader { + struct lt_dlloader *next; + const char *loader_name; /* identifying name for each loader */ + const char *sym_prefix; /* prefix for symbols */ + lt_module_open *module_open; + lt_module_close *module_close; + lt_find_sym *find_sym; + lt_dlloader_exit *dlloader_exit; + lt_user_data dlloader_data; +}; + +struct lt_dlhandle_struct { + struct lt_dlhandle_struct *next; + lt_dlloader *loader; /* dlopening interface */ + lt_dlinfo info; + int depcount; /* number of dependencies */ + lt_dlhandle *deplibs; /* dependencies */ + lt_module module; /* system module handle */ + lt_ptr system; /* system specific data */ + lt_caller_data *caller_data; /* per caller associated data */ + int flags; /* various boolean stats */ +}; + +/* Various boolean flags can be stored in the flags field of an + lt_dlhandle_struct... */ +#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag)) +#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag)) + +#define LT_DLRESIDENT_FLAG (0x01 << 0) +/* ...add more flags here... */ + +#define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG) + + +#define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)] + +static const char objdir[] = LTDL_OBJDIR; +static const char archive_ext[] = LTDL_ARCHIVE_EXT; +#ifdef LTDL_SHLIB_EXT +static const char shlib_ext[] = LTDL_SHLIB_EXT; +#endif +#ifdef LTDL_SYSSEARCHPATH +static const char sys_search_path[] = LTDL_SYSSEARCHPATH; +#endif + + + + +/* --- MUTEX LOCKING --- */ + + +/* Macros to make it easier to run the lock functions only if they have + been registered. The reason for the complicated lock macro is to + ensure that the stored error message from the last error is not + accidentally erased if the current function doesn't generate an + error of its own. */ +#define LT_DLMUTEX_LOCK() LT_STMT_START { \ + if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \ + } LT_STMT_END +#define LT_DLMUTEX_UNLOCK() LT_STMT_START { \ + if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\ + } LT_STMT_END +#define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \ + if (lt_dlmutex_seterror_func) \ + (*lt_dlmutex_seterror_func) (errormsg); \ + else lt_dllast_error = (errormsg); } LT_STMT_END +#define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \ + if (lt_dlmutex_seterror_func) \ + (errormsg) = (*lt_dlmutex_geterror_func) (); \ + else (errormsg) = lt_dllast_error; } LT_STMT_END + +/* The mutex functions stored here are global, and are necessarily the + same for all threads that wish to share access to libltdl. */ +static lt_dlmutex_lock *lt_dlmutex_lock_func = NULL; +static lt_dlmutex_unlock *lt_dlmutex_unlock_func = NULL; +static lt_dlmutex_seterror *lt_dlmutex_seterror_func = NULL; +static lt_dlmutex_geterror *lt_dlmutex_geterror_func = NULL; +static const char *lt_dllast_error = NULL; + + +/* Either set or reset the mutex functions. Either all the arguments must + be valid functions, or else all can be NULL to turn off locking entirely. + The registered functions should be manipulating a static global lock + from the lock() and unlock() callbacks, which needs to be reentrant. */ +int +lt_dlmutex_register (lock, unlock, seterror, geterror) + lt_dlmutex_lock *lock; + lt_dlmutex_unlock *unlock; + lt_dlmutex_seterror *seterror; + lt_dlmutex_geterror *geterror; +{ + lt_dlmutex_unlock *old_unlock = unlock; + int errors = 0; + + /* Lock using the old lock() callback, if any. */ + LT_DLMUTEX_LOCK (); + + if ((lock && unlock && seterror && geterror) + || !(lock || unlock || seterror || geterror)) + { + lt_dlmutex_lock_func = lock; + lt_dlmutex_unlock_func = unlock; + lt_dlmutex_geterror_func = geterror; + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS)); + ++errors; + } + + /* Use the old unlock() callback we saved earlier, if any. Otherwise + record any errors using internal storage. */ + if (old_unlock) + (*old_unlock) (); + + /* Return the number of errors encountered during the execution of + this function. */ + return errors; +} + + + + +/* --- ERROR HANDLING --- */ + + +static const char **user_error_strings = NULL; +static int errorcount = LT_ERROR_MAX; + +int +lt_dladderror (diagnostic) + const char *diagnostic; +{ + int errindex = 0; + int result = -1; + const char **temp = NULL; + + assert (diagnostic); + + LT_DLMUTEX_LOCK (); + + errindex = errorcount - LT_ERROR_MAX; + temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex); + if (temp) + { + user_error_strings = temp; + user_error_strings[errindex] = diagnostic; + result = errorcount++; + } + + LT_DLMUTEX_UNLOCK (); + + return result; +} + +int +lt_dlseterror (errindex) + int errindex; +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + if (errindex >= errorcount || errindex < 0) + { + /* Ack! Error setting the error message! */ + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE)); + ++errors; + } + else if (errindex < LT_ERROR_MAX) + { + /* No error setting the error message! */ + LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]); + } + else + { + /* No error setting the error message! */ + LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]); + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static lt_ptr +lt_emalloc (size) + size_t size; +{ + lt_ptr mem = lt_dlmalloc (size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; +} + +static lt_ptr +lt_erealloc (addr, size) + lt_ptr addr; + size_t size; +{ + lt_ptr mem = realloc (addr, size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; +} + +static char * +lt_estrdup (str) + const char *str; +{ + char *copy = strdup (str); + if (LT_STRLEN (str) && !copy) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return copy; +} + + + + +/* --- DLOPEN() INTERFACE LOADER --- */ + + +/* The Cygwin dlopen implementation prints a spurious error message to + stderr if its call to LoadLibrary() fails for any reason. We can + mitigate this by not using the Cygwin implementation, and falling + back to our own LoadLibrary() wrapper. */ +#if HAVE_LIBDL && !defined(__CYGWIN__) + +/* dynamic linking with dlopen/dlsym */ + +#if HAVE_DLFCN_H +# include <dlfcn.h> +#endif + +#if HAVE_SYS_DL_H +# include <sys/dl.h> +#endif + +#ifdef RTLD_GLOBAL +# define LT_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_GLOBAL DL_GLOBAL +# endif +#endif /* !RTLD_GLOBAL */ +#ifndef LT_GLOBAL +# define LT_GLOBAL 0 +#endif /* !LT_GLOBAL */ + +/* We may have to define LT_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_LAZY_OR_NOW DL_LAZY +# endif +# endif /* !RTLD_LAZY */ +#endif +#ifndef LT_LAZY_OR_NOW +# ifdef RTLD_NOW +# define LT_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_LAZY_OR_NOW DL_NOW +# endif +# endif /* !RTLD_NOW */ +#endif +#ifndef LT_LAZY_OR_NOW +# define LT_LAZY_OR_NOW 0 +#endif /* !LT_LAZY_OR_NOW */ + +#if HAVE_DLERROR +# define DLERROR(arg) dlerror () +#else +# define DLERROR(arg) LT_DLSTRERROR (arg) +#endif + +static lt_module +sys_dl_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW); + + if (!module) + { + LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN)); + } + + return module; +} + +static int +sys_dl_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (dlclose (module) != 0) + { + LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_dl_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = dlsym (module, symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct lt_user_dlloader sys_dl = + { +# ifdef NEED_USCORE + "_", +# else + 0, +# endif + sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 }; + + +#endif /* HAVE_LIBDL */ + + + +/* --- SHL_LOAD() INTERFACE LOADER --- */ + +#if HAVE_SHL_LOAD + +/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */ + +#ifdef HAVE_DL_H +# include <dl.h> +#endif + +/* some flags are missing on some systems, so we provide + * harmless defaults. + * + * Mandatory: + * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. + * BIND_DEFERRED - Delay code symbol resolution until actual reference. + * + * Optionally: + * BIND_FIRST - Place the library at the head of the symbol search + * order. + * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all + * unsatisfied symbols as fatal. This flag allows + * binding of unsatisfied code symbols to be deferred + * until use. + * [Perl: For certain libraries, like DCE, deferred + * binding often causes run time problems. Adding + * BIND_NONFATAL to BIND_IMMEDIATE still allows + * unresolved references in situations like this.] + * BIND_NOSTART - Do not call the initializer for the shared library + * when the library is loaded, nor on a future call to + * shl_unload(). + * BIND_VERBOSE - Print verbose messages concerning possible + * unsatisfied symbols. + * + * hp9000s700/hp9000s800: + * BIND_RESTRICTED - Restrict symbols visible by the library to those + * present at library load time. + * DYNAMIC_PATH - Allow the loader to dynamically search for the + * library specified by the path argument. + */ + +#ifndef DYNAMIC_PATH +# define DYNAMIC_PATH 0 +#endif +#ifndef BIND_RESTRICTED +# define BIND_RESTRICTED 0 +#endif + +#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH) + +static lt_module +sys_shl_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + static shl_t self = (shl_t) 0; + lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); + + /* Since searching for a symbol against a NULL module handle will also + look in everything else that was already loaded and exported with + the -E compiler flag, we always cache a handle saved before any + modules are loaded. */ + if (!self) + { + lt_ptr address; + shl_findsym (&self, "main", TYPE_UNDEFINED, &address); + } + + if (!filename) + { + module = self; + } + else + { + module = shl_load (filename, LT_BIND_FLAGS, 0L); + + if (!module) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + } + } + + return module; +} + +static int +sys_shl_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (module && (shl_unload ((shl_t) (module)) != 0)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_shl_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = NULL; + + /* sys_shl_open should never return a NULL module handle */ + if (module == (lt_module) 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + } + else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address)) + { + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + } + + return address; +} + +static struct lt_user_dlloader sys_shl = { + 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0 +}; + +#endif /* HAVE_SHL_LOAD */ + + + + +/* --- LOADLIBRARY() INTERFACE LOADER --- */ + +#ifdef __WINDOWS__ + +/* dynamic linking for Win32 */ + +#include <windows.h> + +/* Forward declaration; required to implement handle search below. */ +static lt_dlhandle handles; + +static lt_module +sys_wll_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + lt_dlhandle cur; + lt_module module = NULL; + const char *errormsg = NULL; + char *searchname = NULL; + char *ext; + char self_name_buf[MAX_PATH]; + + if (!filename) + { + /* Get the name of main module */ + *self_name_buf = '\0'; + GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf)); + filename = ext = self_name_buf; + } + else + { + ext = strrchr (filename, '.'); + } + + if (ext) + { + /* FILENAME already has an extension. */ + searchname = lt_estrdup (filename); + } + else + { + /* Append a `.' to stop Windows from adding an + implicit `.dll' extension. */ + searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename)); + if (searchname) + sprintf (searchname, "%s.", filename); + } + if (!searchname) + return 0; + +#if __CYGWIN__ + { + char wpath[MAX_PATH]; + cygwin_conv_to_full_win32_path(searchname, wpath); + module = LoadLibrary(wpath); + } +#else + module = LoadLibrary (searchname); +#endif + LT_DLFREE (searchname); + + /* libltdl expects this function to fail if it is unable + to physically load the library. Sadly, LoadLibrary + will search the loaded libraries for a match and return + one of them if the path search load fails. + + We check whether LoadLibrary is returning a handle to + an already loaded module, and simulate failure if we + find one. */ + LT_DLMUTEX_LOCK (); + cur = handles; + while (cur) + { + if (!cur->module) + { + cur = NULL; + break; + } + + if (cur->module == module) + { + break; + } + + cur = cur->next; + } + LT_DLMUTEX_UNLOCK (); + + if (cur || !module) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + module = NULL; + } + + return module; +} + +static int +sys_wll_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (FreeLibrary(module) == 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_wll_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = GetProcAddress (module, symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct lt_user_dlloader sys_wll = { + 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0 +}; + +#endif /* __WINDOWS__ */ + + + + +/* --- LOAD_ADD_ON() INTERFACE LOADER --- */ + + +#ifdef __BEOS__ + +/* dynamic linking for BeOS */ + +#include <kernel/image.h> + +static lt_module +sys_bedl_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + image_id image = 0; + + if (filename) + { + image = load_add_on (filename); + } + else + { + image_info info; + int32 cookie = 0; + if (get_next_image_info (0, &cookie, &info) == B_OK) + image = load_add_on (info.name); + } + + if (image <= 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + image = 0; + } + + return (lt_module) image; +} + +static int +sys_bedl_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (unload_add_on ((image_id) module) != B_OK) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_bedl_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = NULL; + image_id image = (image_id) module; + + if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + address = NULL; + } + + return address; +} + +static struct lt_user_dlloader sys_bedl = { + 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0 +}; + +#endif /* __BEOS__ */ + + + + +/* --- DLD_LINK() INTERFACE LOADER --- */ + + +#if HAVE_DLD + +/* dynamic linking with dld */ + +#if HAVE_DLD_H +#include <dld.h> +#endif + +static lt_module +sys_dld_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + lt_module module = strdup (filename); + + if (dld_link (filename) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + LT_DLFREE (module); + module = NULL; + } + + return module; +} + +static int +sys_dld_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (dld_unlink_by_file ((char*)(module), 1) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + else + { + LT_DLFREE (module); + } + + return errors; +} + +static lt_ptr +sys_dld_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = dld_get_func (symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct lt_user_dlloader sys_dld = { + 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 +}; + +#endif /* HAVE_DLD */ + + + + +/* --- DLPREOPEN() INTERFACE LOADER --- */ + + +/* emulate dynamic linking using preloaded_symbols */ + +typedef struct lt_dlsymlists_t +{ + struct lt_dlsymlists_t *next; + const lt_dlsymlist *syms; +} lt_dlsymlists_t; + +static const lt_dlsymlist *default_preloaded_symbols = NULL; +static lt_dlsymlists_t *preloaded_symbols = NULL; + +static int +presym_init (loader_data) + lt_user_data loader_data; +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + preloaded_symbols = NULL; + if (default_preloaded_symbols) + { + errors = lt_dlpreload (default_preloaded_symbols); + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static int +presym_free_symlists () +{ + lt_dlsymlists_t *lists; + + LT_DLMUTEX_LOCK (); + + lists = preloaded_symbols; + while (lists) + { + lt_dlsymlists_t *tmp = lists; + + lists = lists->next; + LT_DLFREE (tmp); + } + preloaded_symbols = NULL; + + LT_DLMUTEX_UNLOCK (); + + return 0; +} + +static int +presym_exit (loader_data) + lt_user_data loader_data; +{ + presym_free_symlists (); + return 0; +} + +static int +presym_add_symlist (preloaded) + const lt_dlsymlist *preloaded; +{ + lt_dlsymlists_t *tmp; + lt_dlsymlists_t *lists; + int errors = 0; + + LT_DLMUTEX_LOCK (); + + lists = preloaded_symbols; + while (lists) + { + if (lists->syms == preloaded) + { + goto done; + } + lists = lists->next; + } + + tmp = LT_EMALLOC (lt_dlsymlists_t, 1); + if (tmp) + { + memset (tmp, 0, sizeof(lt_dlsymlists_t)); + tmp->syms = preloaded; + tmp->next = preloaded_symbols; + preloaded_symbols = tmp; + } + else + { + ++errors; + } + + done: + LT_DLMUTEX_UNLOCK (); + return errors; +} + +static lt_module +presym_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + lt_dlsymlists_t *lists; + lt_module module = (lt_module) 0; + + LT_DLMUTEX_LOCK (); + lists = preloaded_symbols; + + if (!lists) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS)); + goto done; + } + + /* Can't use NULL as the reflective symbol header, as NULL is + used to mark the end of the entire symbol list. Self-dlpreopened + symbols follow this magic number, chosen to be an unlikely + clash with a real module name. */ + if (!filename) + { + filename = "@PROGRAM@"; + } + + while (lists) + { + const lt_dlsymlist *syms = lists->syms; + + while (syms->name) + { + if (!syms->address && strcmp(syms->name, filename) == 0) + { + module = (lt_module) syms; + goto done; + } + ++syms; + } + + lists = lists->next; + } + + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + + done: + LT_DLMUTEX_UNLOCK (); + return module; +} + +static int +presym_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + /* Just to silence gcc -Wall */ + module = NULL; + return 0; +} + +static lt_ptr +presym_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_dlsymlist *syms = (lt_dlsymlist*) module; + + ++syms; + while (syms->address) + { + if (strcmp(syms->name, symbol) == 0) + { + return syms->address; + } + + ++syms; + } + + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + + return 0; +} + +static struct lt_user_dlloader presym = { + 0, presym_open, presym_close, presym_sym, presym_exit, 0 +}; + + + + + +/* --- DYNAMIC MODULE LOADING --- */ + + +/* The type of a function used at each iteration of foreach_dirinpath(). */ +typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + +static int foreach_dirinpath LT_PARAMS((const char *search_path, + const char *base_name, + foreach_callback_func *func, + lt_ptr data1, lt_ptr data2)); + +static int find_file_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + + +static int canonicalize_path LT_PARAMS((const char *path, + char **pcanonical)); +static int argzize_path LT_PARAMS((const char *path, + char **pargz, + size_t *pargz_len)); +static FILE *find_file LT_PARAMS((const char *search_path, + const char *base_name, + char **pdir)); +static lt_dlhandle *find_handle LT_PARAMS((const char *search_path, + const char *base_name, + lt_dlhandle *handle)); +static int find_module LT_PARAMS((lt_dlhandle *handle, + const char *dir, + const char *libdir, + const char *dlname, + const char *old_name, + int installed)); +static int free_vars LT_PARAMS((char *dlname, char *oldname, + char *libdir, char *deplibs)); +static int load_deplibs LT_PARAMS((lt_dlhandle handle, + char *deplibs)); +static int trim LT_PARAMS((char **dest, + const char *str)); +static int try_dlopen LT_PARAMS((lt_dlhandle *handle, + const char *filename)); +static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, + const char *filename)); +static int unload_deplibs LT_PARAMS((lt_dlhandle handle)); +static int lt_argz_insert LT_PARAMS((char **pargz, + size_t *pargz_len, + char *before, + const char *entry)); +static int lt_argz_insertinorder LT_PARAMS((char **pargz, + size_t *pargz_len, + const char *entry)); +static int lt_argz_insertdir LT_PARAMS((char **pargz, + size_t *pargz_len, + const char *dirnam, + struct dirent *dp)); +static int lt_dlpath_insertdir LT_PARAMS((char **ppath, + char *before, + const char *dir)); +static int list_files_by_dir LT_PARAMS((const char *dirnam, + char **pargz, + size_t *pargz_len)); +static int file_not_found LT_PARAMS((void)); + +static char *user_search_path= NULL; +static lt_dlloader *loaders = NULL; +static lt_dlhandle handles = NULL; +static int initialized = 0; + +/* Initialize libltdl. */ +int +lt_dlinit () +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + /* Initialize only at first call. */ + if (++initialized == 1) + { + handles = NULL; + user_search_path = NULL; /* empty search path */ + +#if HAVE_LIBDL && !defined(__CYGWIN__) + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen"); +#endif +#if HAVE_SHL_LOAD + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen"); +#endif +#ifdef __WINDOWS__ + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen"); +#endif +#ifdef __BEOS__ + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen"); +#endif +#if HAVE_DLD + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld"); +#endif + errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload"); + + if (presym_init (presym.dlloader_data)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER)); + ++errors; + } + else if (errors != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED)); + ++errors; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +int +lt_dlpreload (preloaded) + const lt_dlsymlist *preloaded; +{ + int errors = 0; + + if (preloaded) + { + errors = presym_add_symlist (preloaded); + } + else + { + presym_free_symlists(); + + LT_DLMUTEX_LOCK (); + if (default_preloaded_symbols) + { + errors = lt_dlpreload (default_preloaded_symbols); + } + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +lt_dlpreload_default (preloaded) + const lt_dlsymlist *preloaded; +{ + LT_DLMUTEX_LOCK (); + default_preloaded_symbols = preloaded; + LT_DLMUTEX_UNLOCK (); + return 0; +} + +int +lt_dlexit () +{ + /* shut down libltdl */ + lt_dlloader *loader; + int errors = 0; + + LT_DLMUTEX_LOCK (); + loader = loaders; + + if (!initialized) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN)); + ++errors; + goto done; + } + + /* shut down only at last call. */ + if (--initialized == 0) + { + int level; + + while (handles && LT_DLIS_RESIDENT (handles)) + { + handles = handles->next; + } + + /* close all modules */ + for (level = 1; handles; ++level) + { + lt_dlhandle cur = handles; + int saw_nonresident = 0; + + while (cur) + { + lt_dlhandle tmp = cur; + cur = cur->next; + if (!LT_DLIS_RESIDENT (tmp)) + saw_nonresident = 1; + if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level) + { + if (lt_dlclose (tmp)) + { + ++errors; + } + } + } + /* done if only resident modules are left */ + if (!saw_nonresident) + break; + } + + /* close all loaders */ + while (loader) + { + lt_dlloader *next = loader->next; + lt_user_data data = loader->dlloader_data; + if (loader->dlloader_exit && loader->dlloader_exit (data)) + { + ++errors; + } + + LT_DLMEM_REASSIGN (loader, next); + } + loaders = NULL; + } + + done: + LT_DLMUTEX_UNLOCK (); + return errors; +} + +static int +tryall_dlopen (handle, filename) + lt_dlhandle *handle; + const char *filename; +{ + lt_dlhandle cur; + lt_dlloader *loader; + const char *saved_error; + int errors = 0; + + LT_DLMUTEX_GETERROR (saved_error); + LT_DLMUTEX_LOCK (); + + cur = handles; + loader = loaders; + + /* check whether the module was already opened */ + while (cur) + { + /* try to dlopen the program itself? */ + if (!cur->info.filename && !filename) + { + break; + } + + if (cur->info.filename && filename + && strcmp (cur->info.filename, filename) == 0) + { + break; + } + + cur = cur->next; + } + + if (cur) + { + ++cur->info.ref_count; + *handle = cur; + goto done; + } + + cur = *handle; + if (filename) + { + cur->info.filename = lt_estrdup (filename); + if (!cur->info.filename) + { + ++errors; + goto done; + } + } + else + { + cur->info.filename = NULL; + } + + while (loader) + { + lt_user_data data = loader->dlloader_data; + + cur->module = loader->module_open (data, filename); + + if (cur->module != NULL) + { + break; + } + loader = loader->next; + } + + if (!loader) + { + LT_DLFREE (cur->info.filename); + ++errors; + goto done; + } + + cur->loader = loader; + LT_DLMUTEX_SETERROR (saved_error); + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static int +tryall_dlopen_module (handle, prefix, dirname, dlname) + lt_dlhandle *handle; + const char *prefix; + const char *dirname; + const char *dlname; +{ + int error = 0; + char *filename = NULL; + size_t filename_len = 0; + size_t dirname_len = LT_STRLEN (dirname); + + assert (handle); + assert (dirname); + assert (dlname); +#ifdef LT_DIRSEP_CHAR + /* Only canonicalized names (i.e. with DIRSEP chars already converted) + should make it into this function: */ + assert (strchr (dirname, LT_DIRSEP_CHAR) == NULL); +#endif + + if (dirname[dirname_len -1] == '/') + --dirname_len; + filename_len = dirname_len + 1 + LT_STRLEN (dlname); + + /* Allocate memory, and combine DIRNAME and MODULENAME into it. + The PREFIX (if any) is handled below. */ + filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1); + if (!filename) + return 1; + + sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname); + + /* Now that we have combined DIRNAME and MODULENAME, if there is + also a PREFIX to contend with, simply recurse with the arguments + shuffled. Otherwise, attempt to open FILENAME as a module. */ + if (prefix) + { + error += tryall_dlopen_module (handle, + (const char *) 0, prefix, filename); + } + else if (tryall_dlopen (handle, filename) != 0) + { + ++error; + } + + LT_DLFREE (filename); + return error; +} + +static int +find_module (handle, dir, libdir, dlname, old_name, installed) + lt_dlhandle *handle; + const char *dir; + const char *libdir; + const char *dlname; + const char *old_name; + int installed; +{ + /* Try to open the old library first; if it was dlpreopened, + we want the preopened version of it, even if a dlopenable + module is available. */ + if (old_name && tryall_dlopen (handle, old_name) == 0) + { + return 0; + } + + /* Try to open the dynamic library. */ + if (dlname) + { + /* try to open the installed module */ + if (installed && libdir) + { + if (tryall_dlopen_module (handle, + (const char *) 0, libdir, dlname) == 0) + return 0; + } + + /* try to open the not-installed module */ + if (!installed) + { + if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0) + return 0; + } + + /* maybe it was moved to another directory */ + { + if (tryall_dlopen_module (handle, + (const char *) 0, dir, dlname) == 0) + return 0; + } + } + + return 1; +} + + +static int +canonicalize_path (path, pcanonical) + const char *path; + char **pcanonical; +{ + char *canonical = NULL; + + assert (path && *path); + assert (pcanonical); + + canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path)); + if (!canonical) + return 1; + + { + size_t dest = 0; + size_t src; + for (src = 0; path[src] != LT_EOS_CHAR; ++src) + { + /* Path separators are not copied to the beginning or end of + the destination, or if another separator would follow + immediately. */ + if (path[src] == LT_PATHSEP_CHAR) + { + if ((dest == 0) + || (path[1+ src] == LT_PATHSEP_CHAR) + || (path[1+ src] == LT_EOS_CHAR)) + continue; + } + + /* Anything other than a directory separator is copied verbatim. */ + if ((path[src] != '/') +#ifdef LT_DIRSEP_CHAR + && (path[src] != LT_DIRSEP_CHAR) +#endif + ) + { + canonical[dest++] = path[src]; + } + /* Directory separators are converted and copied only if they are + not at the end of a path -- i.e. before a path separator or + NULL terminator. */ + else if ((path[1+ src] != LT_PATHSEP_CHAR) + && (path[1+ src] != LT_EOS_CHAR) +#ifdef LT_DIRSEP_CHAR + && (path[1+ src] != LT_DIRSEP_CHAR) +#endif + && (path[1+ src] != '/')) + { + canonical[dest++] = '/'; + } + } + + /* Add an end-of-string marker at the end. */ + canonical[dest] = LT_EOS_CHAR; + } + + /* Assign new value. */ + *pcanonical = canonical; + + return 0; +} + +static int +argzize_path (path, pargz, pargz_len) + const char *path; + char **pargz; + size_t *pargz_len; +{ + error_t error; + + assert (path); + assert (pargz); + assert (pargz_len); + + if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len))) + { + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + + return 1; + } + + return 0; +} + +/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element + of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns + non-zero or all elements are exhausted. If BASE_NAME is non-NULL, + it is appended to each SEARCH_PATH element before FUNC is called. */ +static int +foreach_dirinpath (search_path, base_name, func, data1, data2) + const char *search_path; + const char *base_name; + foreach_callback_func *func; + lt_ptr data1; + lt_ptr data2; +{ + int result = 0; + int filenamesize = 0; + size_t lenbase = LT_STRLEN (base_name); + size_t argz_len = 0; + char *argz = NULL; + char *filename = NULL; + char *canonical = NULL; + + LT_DLMUTEX_LOCK (); + + if (!search_path || !*search_path) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + goto cleanup; + } + + if (canonicalize_path (search_path, &canonical) != 0) + goto cleanup; + + if (argzize_path (canonical, &argz, &argz_len) != 0) + goto cleanup; + + { + char *dir_name = NULL; + while ((dir_name = argz_next (argz, argz_len, dir_name))) + { + size_t lendir = LT_STRLEN (dir_name); + + if (lendir +1 +lenbase >= filenamesize) + { + LT_DLFREE (filename); + filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */ + filename = LT_EMALLOC (char, filenamesize); + if (!filename) + goto cleanup; + } + + assert (filenamesize > lendir); + strcpy (filename, dir_name); + + if (base_name && *base_name) + { + if (filename[lendir -1] != '/') + filename[lendir++] = '/'; + strcpy (filename +lendir, base_name); + } + + if ((result = (*func) (filename, data1, data2))) + { + break; + } + } + } + + cleanup: + LT_DLFREE (argz); + LT_DLFREE (canonical); + LT_DLFREE (filename); + + LT_DLMUTEX_UNLOCK (); + + return result; +} + +/* If FILEPATH can be opened, store the name of the directory component + in DATA1, and the opened FILE* structure address in DATA2. Otherwise + DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */ +static int +find_file_callback (filename, data1, data2) + char *filename; + lt_ptr data1; + lt_ptr data2; +{ + char **pdir = (char **) data1; + FILE **pfile = (FILE **) data2; + int is_done = 0; + + assert (filename && *filename); + assert (pdir); + assert (pfile); + + if ((*pfile = fopen (filename, LT_READTEXT_MODE))) + { + char *dirend = strrchr (filename, '/'); + + if (dirend > filename) + *dirend = LT_EOS_CHAR; + + LT_DLFREE (*pdir); + *pdir = lt_estrdup (filename); + is_done = (*pdir == NULL) ? -1 : 1; + } + + return is_done; +} + +static FILE * +find_file (search_path, base_name, pdir) + const char *search_path; + const char *base_name; + char **pdir; +{ + FILE *file = NULL; + + foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file); + + return file; +} + +static int +find_handle_callback (filename, data, ignored) + char *filename; + lt_ptr data; + lt_ptr ignored; +{ + lt_dlhandle *handle = (lt_dlhandle *) data; + int notfound = access (filename, R_OK); + + /* Bail out if file cannot be read... */ + if (notfound) + return 0; + + /* Try to dlopen the file, but do not continue searching in any + case. */ + if (tryall_dlopen (handle, filename) != 0) + *handle = NULL; + + return 1; +} + +/* If HANDLE was found return it, otherwise return 0. If HANDLE was + found but could not be opened, *HANDLE will be set to 0. */ +static lt_dlhandle * +find_handle (search_path, base_name, handle) + const char *search_path; + const char *base_name; + lt_dlhandle *handle; +{ + if (!search_path) + return 0; + + if (!foreach_dirinpath (search_path, base_name, find_handle_callback, + handle, 0)) + return 0; + + return handle; +} + +static int +load_deplibs (handle, deplibs) + lt_dlhandle handle; + char *deplibs; +{ +#if LTDL_DLOPEN_DEPLIBS + char *p, *save_search_path = NULL; + int depcount = 0; + int i; + char **names = NULL; +#endif + int errors = 0; + + handle->depcount = 0; + +#if LTDL_DLOPEN_DEPLIBS + if (!deplibs) + { + return errors; + } + ++errors; + + LT_DLMUTEX_LOCK (); + if (user_search_path) + { + save_search_path = lt_estrdup (user_search_path); + if (!save_search_path) + goto cleanup; + } + + /* extract search paths and count deplibs */ + p = deplibs; + while (*p) + { + if (!isspace ((int) *p)) + { + char *end = p+1; + while (*end && !isspace((int) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0) + { + char save = *end; + *end = '\0'; /* set a temporary string terminator */ + if (lt_dladdsearchdir(p+2)) + { + goto cleanup; + } + *end = save; + } + else + { + ++depcount; + } + + p = end; + } + else + { + ++p; + } + } + + /* restore the old search path */ + LT_DLFREE (user_search_path); + user_search_path = save_search_path; + + LT_DLMUTEX_UNLOCK (); + + if (!depcount) + { + errors = 0; + goto cleanup; + } + + names = LT_EMALLOC (char *, depcount * sizeof (char*)); + if (!names) + goto cleanup; + + /* now only extract the actual deplibs */ + depcount = 0; + p = deplibs; + while (*p) + { + if (isspace ((int) *p)) + { + ++p; + } + else + { + char *end = p+1; + while (*end && !isspace ((int) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0) + { + char *name; + char save = *end; + *end = '\0'; /* set a temporary string terminator */ + if (strncmp(p, "-l", 2) == 0) + { + size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); + name = LT_EMALLOC (char, 1+ name_len); + if (name) + sprintf (name, "lib%s", p+2); + } + else + name = lt_estrdup(p); + + if (!name) + goto cleanup_names; + + names[depcount++] = name; + *end = save; + } + p = end; + } + } + + /* load the deplibs (in reverse order) + At this stage, don't worry if the deplibs do not load correctly, + they may already be statically linked into the loading application + for instance. There will be a more enlightening error message + later on if the loaded module cannot resolve all of its symbols. */ + if (depcount) + { + int j = 0; + + handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount); + if (!handle->deplibs) + goto cleanup; + + for (i = 0; i < depcount; ++i) + { + handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]); + if (handle->deplibs[j]) + { + ++j; + } + } + + handle->depcount = j; /* Number of successfully loaded deplibs */ + errors = 0; + } + + cleanup_names: + for (i = 0; i < depcount; ++i) + { + LT_DLFREE (names[i]); + } + + cleanup: + LT_DLFREE (names); +#endif + + return errors; +} + +static int +unload_deplibs (handle) + lt_dlhandle handle; +{ + int i; + int errors = 0; + + if (handle->depcount) + { + for (i = 0; i < handle->depcount; ++i) + { + if (!LT_DLIS_RESIDENT (handle->deplibs[i])) + { + errors += lt_dlclose (handle->deplibs[i]); + } + } + } + + return errors; +} + +static int +trim (dest, str) + char **dest; + const char *str; +{ + /* remove the leading and trailing "'" from str + and store the result in dest */ + const char *end = strrchr (str, '\''); + size_t len = LT_STRLEN (str); + char *tmp; + + LT_DLFREE (*dest); + + if (len > 3 && str[0] == '\'') + { + tmp = LT_EMALLOC (char, end - str); + if (!tmp) + return 1; + + strncpy(tmp, &str[1], (end - str) - 1); + tmp[len-3] = LT_EOS_CHAR; + *dest = tmp; + } + else + { + *dest = NULL; + } + + return 0; +} + +static int +free_vars (dlname, oldname, libdir, deplibs) + char *dlname; + char *oldname; + char *libdir; + char *deplibs; +{ + LT_DLFREE (dlname); + LT_DLFREE (oldname); + LT_DLFREE (libdir); + LT_DLFREE (deplibs); + + return 0; +} + +static int +try_dlopen (phandle, filename) + lt_dlhandle *phandle; + const char *filename; +{ + const char * ext = NULL; + const char * saved_error = NULL; + char * canonical = NULL; + char * base_name = NULL; + char * dir = NULL; + char * name = NULL; + int errors = 0; + lt_dlhandle newhandle; + + assert (phandle); + assert (*phandle == NULL); + + LT_DLMUTEX_GETERROR (saved_error); + + /* dlopen self? */ + if (!filename) + { + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == NULL) + return 1; + + memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); + newhandle = *phandle; + + /* lt_dlclose()ing yourself is very bad! Disallow it. */ + LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG); + + if (tryall_dlopen (&newhandle, 0) != 0) + { + LT_DLFREE (*phandle); + return 1; + } + + goto register_handle; + } + + assert (filename && *filename); + + /* Doing this immediately allows internal functions to safely + assume only canonicalized paths are passed. */ + if (canonicalize_path (filename, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + /* If the canonical module name is a path (relative or absolute) + then split it into a directory part and a name part. */ + base_name = strrchr (canonical, '/'); + if (base_name) + { + size_t dirlen = (1+ base_name) - canonical; + + dir = LT_EMALLOC (char, 1+ dirlen); + if (!dir) + { + ++errors; + goto cleanup; + } + + strncpy (dir, canonical, dirlen); + dir[dirlen] = LT_EOS_CHAR; + + ++base_name; + } + else + LT_DLMEM_REASSIGN (base_name, canonical); + + assert (base_name && *base_name); + + /* Check whether we are opening a libtool module (.la extension). */ + ext = strrchr (base_name, '.'); + if (ext && strcmp (ext, archive_ext) == 0) + { + /* this seems to be a libtool module */ + FILE * file = NULL; + char * dlname = NULL; + char * old_name = NULL; + char * libdir = NULL; + char * deplibs = NULL; + char * line = NULL; + size_t line_len; + + /* if we can't find the installed flag, it is probably an + installed libtool archive, produced with an old version + of libtool */ + int installed = 1; + + /* extract the module name from the file name */ + name = LT_EMALLOC (char, ext - base_name + 1); + if (!name) + { + ++errors; + goto cleanup; + } + + /* canonicalize the module name */ + { + size_t i; + for (i = 0; i < ext - base_name; ++i) + { + if (isalnum ((int)(base_name[i]))) + { + name[i] = base_name[i]; + } + else + { + name[i] = '_'; + } + } + name[ext - base_name] = LT_EOS_CHAR; + } + + /* Now try to open the .la file. If there is no directory name + component, try to find it first in user_search_path and then other + prescribed paths. Otherwise (or in any case if the module was not + yet found) try opening just the module name as passed. */ + if (!dir) + { + const char *search_path; + + LT_DLMUTEX_LOCK (); + search_path = user_search_path; + if (search_path) + file = find_file (user_search_path, base_name, &dir); + LT_DLMUTEX_UNLOCK (); + + if (!file) + { + search_path = getenv (LTDL_SEARCHPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } + +#ifdef LTDL_SHLIBPATH_VAR + if (!file) + { + search_path = getenv (LTDL_SHLIBPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } +#endif +#ifdef LTDL_SYSSEARCHPATH + if (!file && sys_search_path) + { + file = find_file (sys_search_path, base_name, &dir); + } +#endif + } + if (!file) + { + file = fopen (filename, LT_READTEXT_MODE); + } + + /* If we didn't find the file by now, it really isn't there. Set + the status flag, and bail out. */ + if (!file) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + ++errors; + goto cleanup; + } + + line_len = LT_FILENAME_MAX; + line = LT_EMALLOC (char, line_len); + if (!line) + { + fclose (file); + ++errors; + goto cleanup; + } + + /* read the .la file */ + while (!feof (file)) + { + if (!fgets (line, (int) line_len, file)) + { + break; + } + + /* Handle the case where we occasionally need to read a line + that is longer than the initial buffer size. */ + while (line[LT_STRLEN(line) -1] != '\n') + { + line = LT_DLREALLOC (char, line, line_len *2); + if (!fgets (&line[line_len -1], (int) line_len +1, file)) + { + break; + } + line_len *= 2; + } + + if (line[0] == '\n' || line[0] == '#') + { + continue; + } + +#undef STR_DLNAME +#define STR_DLNAME "dlname=" + if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) + { + errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); + } + +#undef STR_OLD_LIBRARY +#define STR_OLD_LIBRARY "old_library=" + else if (strncmp (line, STR_OLD_LIBRARY, + sizeof (STR_OLD_LIBRARY) - 1) == 0) + { + errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); + } +#undef STR_LIBDIR +#define STR_LIBDIR "libdir=" + else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) + { + errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); + } + +#undef STR_DL_DEPLIBS +#define STR_DL_DEPLIBS "dependency_libs=" + else if (strncmp (line, STR_DL_DEPLIBS, + sizeof (STR_DL_DEPLIBS) - 1) == 0) + { + errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); + } + else if (strcmp (line, "installed=yes\n") == 0) + { + installed = 1; + } + else if (strcmp (line, "installed=no\n") == 0) + { + installed = 0; + } + +#undef STR_LIBRARY_NAMES +#define STR_LIBRARY_NAMES "library_names=" + else if (! dlname && strncmp (line, STR_LIBRARY_NAMES, + sizeof (STR_LIBRARY_NAMES) - 1) == 0) + { + char *last_libname; + errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); + if (!errors + && dlname + && (last_libname = strrchr (dlname, ' ')) != NULL) + { + last_libname = lt_estrdup (last_libname + 1); + if (!last_libname) + { + ++errors; + goto cleanup; + } + LT_DLMEM_REASSIGN (dlname, last_libname); + } + } + + if (errors) + break; + } + + fclose (file); + LT_DLFREE (line); + + /* allocate the handle */ + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == NULL) + ++errors; + + if (errors) + { + free_vars (dlname, old_name, libdir, deplibs); + LT_DLFREE (*phandle); + goto cleanup; + } + + assert (*phandle); + + memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); + if (load_deplibs (*phandle, deplibs) == 0) + { + newhandle = *phandle; + /* find_module may replace newhandle */ + if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) + { + unload_deplibs (*phandle); + ++errors; + } + } + else + { + ++errors; + } + + free_vars (dlname, old_name, libdir, deplibs); + if (errors) + { + LT_DLFREE (*phandle); + goto cleanup; + } + + if (*phandle != newhandle) + { + unload_deplibs (*phandle); + } + } + else + { + /* not a libtool module */ + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == NULL) + { + ++errors; + goto cleanup; + } + + memset (*phandle, 0, sizeof (struct lt_dlhandle_struct)); + newhandle = *phandle; + + /* If the module has no directory name component, try to find it + first in user_search_path and then other prescribed paths. + Otherwise (or in any case if the module was not yet found) try + opening just the module name as passed. */ + if ((dir || (!find_handle (user_search_path, base_name, &newhandle) + && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, + &newhandle) +#ifdef LTDL_SHLIBPATH_VAR + && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name, + &newhandle) +#endif +#ifdef LTDL_SYSSEARCHPATH + && !find_handle (sys_search_path, base_name, &newhandle) +#endif + ))) + { + if (tryall_dlopen (&newhandle, filename) != 0) + { + newhandle = NULL; + } + } + + if (!newhandle) + { + LT_DLFREE (*phandle); + ++errors; + goto cleanup; + } + } + + register_handle: + LT_DLMEM_REASSIGN (*phandle, newhandle); + + if ((*phandle)->info.ref_count == 0) + { + (*phandle)->info.ref_count = 1; + LT_DLMEM_REASSIGN ((*phandle)->info.name, name); + + LT_DLMUTEX_LOCK (); + (*phandle)->next = handles; + handles = *phandle; + LT_DLMUTEX_UNLOCK (); + } + + LT_DLMUTEX_SETERROR (saved_error); + + cleanup: + LT_DLFREE (dir); + LT_DLFREE (name); + LT_DLFREE (canonical); + + return errors; +} + +lt_dlhandle +lt_dlopen (filename) + const char *filename; +{ + lt_dlhandle handle = NULL; + + /* Just incase we missed a code path in try_dlopen() that reports + an error, but forgets to reset handle... */ + if (try_dlopen (&handle, filename) != 0) + return 0; + + return handle; +} + +/* If the last error messge store was `FILE_NOT_FOUND', then return + non-zero. */ +static int +file_not_found () +{ + const char *error = NULL; + + LT_DLMUTEX_GETERROR (error); + if (error == LT_DLSTRERROR (FILE_NOT_FOUND)) + return 1; + + return 0; +} + +/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to + open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, + and if a file is still not found try again with SHLIB_EXT appended + instead. */ +lt_dlhandle +lt_dlopenext (filename) + const char *filename; +{ + lt_dlhandle handle = NULL; + char * tmp = NULL; + char * ext = NULL; + size_t len; + int errors = 0; + + if (!filename) + { + return lt_dlopen (filename); + } + + assert (filename); + + len = LT_STRLEN (filename); + ext = strrchr (filename, '.'); + + /* If FILENAME already bears a suitable extension, there is no need + to try appending additional extensions. */ + if (ext && ((strcmp (ext, archive_ext) == 0) +#ifdef LTDL_SHLIB_EXT + || (strcmp (ext, shlib_ext) == 0) +#endif + )) + { + return lt_dlopen (filename); + } + + /* First try appending ARCHIVE_EXT. */ + tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1); + if (!tmp) + return 0; + + strcpy (tmp, filename); + strcat (tmp, archive_ext); + errors = try_dlopen (&handle, tmp); + + /* If we found FILENAME, stop searching -- whether we were able to + load the file as a module or not. If the file exists but loading + failed, it is better to return an error message here than to + report FILE_NOT_FOUND when the alternatives (foo.so etc) are not + in the module search path. */ + if (handle || ((errors > 0) && file_not_found ())) + { + LT_DLFREE (tmp); + return handle; + } + +#ifdef LTDL_SHLIB_EXT + /* Try appending SHLIB_EXT. */ + if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext)) + { + LT_DLFREE (tmp); + tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1); + if (!tmp) + return 0; + + strcpy (tmp, filename); + } + else + { + tmp[len] = LT_EOS_CHAR; + } + + strcat(tmp, shlib_ext); + errors = try_dlopen (&handle, tmp); + + /* As before, if the file was found but loading failed, return now + with the current error message. */ + if (handle || ((errors > 0) && file_not_found ())) + { + LT_DLFREE (tmp); + return handle; + } +#endif + + /* Still here? Then we really did fail to locate any of the file + names we tried. */ + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + LT_DLFREE (tmp); + return 0; +} + + +static int +lt_argz_insert (pargz, pargz_len, before, entry) + char **pargz; + size_t *pargz_len; + char *before; + const char *entry; +{ + error_t error; + + if ((error = argz_insert (pargz, pargz_len, before, entry))) + { + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + return 1; + } + + return 0; +} + +static int +lt_argz_insertinorder (pargz, pargz_len, entry) + char **pargz; + size_t *pargz_len; + const char *entry; +{ + char *before = NULL; + + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + if (*pargz) + while ((before = argz_next (*pargz, *pargz_len, before))) + { + int cmp = strcmp (entry, before); + + if (cmp < 0) break; + if (cmp == 0) return 0; /* No duplicates! */ + } + + return lt_argz_insert (pargz, pargz_len, before, entry); +} + +static int +lt_argz_insertdir (pargz, pargz_len, dirnam, dp) + char **pargz; + size_t *pargz_len; + const char *dirnam; + struct dirent *dp; +{ + char *buf = NULL; + size_t buf_len = 0; + char *end = NULL; + size_t end_offset = 0; + size_t dir_len = 0; + int errors = 0; + + assert (pargz); + assert (pargz_len); + assert (dp); + + dir_len = LT_STRLEN (dirnam); + end = dp->d_name + LT_D_NAMLEN(dp); + + /* Ignore version numbers. */ + { + char *p; + for (p = end; p -1 > dp->d_name; --p) + if (strchr (".0123456789", p[-1]) == 0) + break; + + if (*p == '.') + end = p; + } + + /* Ignore filename extension. */ + { + char *p; + for (p = end -1; p > dp->d_name; --p) + if (*p == '.') + { + end = p; + break; + } + } + + /* Prepend the directory name. */ + end_offset = end - dp->d_name; + buf_len = dir_len + 1+ end_offset; + buf = LT_EMALLOC (char, 1+ buf_len); + if (!buf) + return ++errors; + + assert (buf); + + strcpy (buf, dirnam); + strcat (buf, "/"); + strncat (buf, dp->d_name, end_offset); + buf[buf_len] = LT_EOS_CHAR; + + /* Try to insert (in order) into ARGZ/ARGZ_LEN. */ + if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0) + ++errors; + + LT_DLFREE (buf); + + return errors; +} + +static int +list_files_by_dir (dirnam, pargz, pargz_len) + const char *dirnam; + char **pargz; + size_t *pargz_len; +{ + DIR *dirp = NULL; + int errors = 0; + + assert (dirnam && *dirnam); + assert (pargz); + assert (pargz_len); + assert (dirnam[LT_STRLEN(dirnam) -1] != '/'); + + dirp = opendir (dirnam); + if (dirp) + { + struct dirent *dp = NULL; + + while ((dp = readdir (dirp))) + if (dp->d_name[0] != '.') + if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp)) + { + ++errors; + break; + } + + closedir (dirp); + } + else + ++errors; + + return errors; +} + + +/* If there are any files in DIRNAME, call the function passed in + DATA1 (with the name of each file and DATA2 as arguments). */ +static int +foreachfile_callback (dirname, data1, data2) + char *dirname; + lt_ptr data1; + lt_ptr data2; +{ + int (*func) LT_PARAMS((const char *filename, lt_ptr data)) + = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1; + + int is_done = 0; + char *argz = NULL; + size_t argz_len = 0; + + if (list_files_by_dir (dirname, &argz, &argz_len) != 0) + goto cleanup; + if (!argz) + goto cleanup; + + { + char *filename = NULL; + while ((filename = argz_next (argz, argz_len, filename))) + if ((is_done = (*func) (filename, data2))) + break; + } + + cleanup: + LT_DLFREE (argz); + + return is_done; +} + + +/* Call FUNC for each unique extensionless file in SEARCH_PATH, along + with DATA. The filenames passed to FUNC would be suitable for + passing to lt_dlopenext. The extensions are stripped so that + individual modules do not generate several entries (e.g. libfoo.la, + libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL, + then the same directories that lt_dlopen would search are examined. */ +int +lt_dlforeachfile (search_path, func, data) + const char *search_path; + int (*func) LT_PARAMS ((const char *filename, lt_ptr data)); + lt_ptr data; +{ + int is_done = 0; + + if (search_path) + { + /* If a specific path was passed, search only the directories + listed in it. */ + is_done = foreach_dirinpath (search_path, 0, + foreachfile_callback, func, data); + } + else + { + /* Otherwise search the default paths. */ + is_done = foreach_dirinpath (user_search_path, 0, + foreachfile_callback, func, data); + if (!is_done) + { + is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0, + foreachfile_callback, func, data); + } + +#ifdef LTDL_SHLIBPATH_VAR + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0, + foreachfile_callback, func, data); + } +#endif +#ifdef LTDL_SYSSEARCHPATH + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0, + foreachfile_callback, func, data); + } +#endif + } + + return is_done; +} + +int +lt_dlclose (handle) + lt_dlhandle handle; +{ + lt_dlhandle cur, last; + int errors = 0; + + LT_DLMUTEX_LOCK (); + + /* check whether the handle is valid */ + last = cur = handles; + while (cur && handle != cur) + { + last = cur; + cur = cur->next; + } + + if (!cur) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + ++errors; + goto done; + } + + handle->info.ref_count--; + + /* Note that even with resident modules, we must track the ref_count + correctly incase the user decides to reset the residency flag + later (even though the API makes no provision for that at the + moment). */ + if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle)) + { + lt_user_data data = handle->loader->dlloader_data; + + if (handle != handles) + { + last->next = handle->next; + } + else + { + handles = handle->next; + } + + errors += handle->loader->module_close (data, handle->module); + errors += unload_deplibs(handle); + + /* It is up to the callers to free the data itself. */ + LT_DLFREE (handle->caller_data); + + LT_DLFREE (handle->info.filename); + LT_DLFREE (handle->info.name); + LT_DLFREE (handle); + + goto done; + } + + if (LT_DLIS_RESIDENT (handle)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE)); + ++errors; + } + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +lt_ptr +lt_dlsym (handle, symbol) + lt_dlhandle handle; + const char *symbol; +{ + size_t lensym; + char lsym[LT_SYMBOL_LENGTH]; + char *sym; + lt_ptr address; + lt_user_data data; + + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return 0; + } + + if (!symbol) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + return 0; + } + + lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix) + + LT_STRLEN (handle->info.name); + + if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH) + { + sym = lsym; + } + else + { + sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); + if (!sym) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW)); + return 0; + } + } + + data = handle->loader->dlloader_data; + if (handle->info.name) + { + const char *saved_error; + + LT_DLMUTEX_GETERROR (saved_error); + + /* this is a libtool module */ + if (handle->loader->sym_prefix) + { + strcpy(sym, handle->loader->sym_prefix); + strcat(sym, handle->info.name); + } + else + { + strcpy(sym, handle->info.name); + } + + strcat(sym, "_LTX_"); + strcat(sym, symbol); + + /* try "modulename_LTX_symbol" */ + address = handle->loader->find_sym (data, handle->module, sym); + if (address) + { + if (sym != lsym) + { + LT_DLFREE (sym); + } + return address; + } + LT_DLMUTEX_SETERROR (saved_error); + } + + /* otherwise try "symbol" */ + if (handle->loader->sym_prefix) + { + strcpy(sym, handle->loader->sym_prefix); + strcat(sym, symbol); + } + else + { + strcpy(sym, symbol); + } + + address = handle->loader->find_sym (data, handle->module, sym); + if (sym != lsym) + { + LT_DLFREE (sym); + } + + return address; +} + +const char * +lt_dlerror () +{ + const char *error; + + LT_DLMUTEX_GETERROR (error); + LT_DLMUTEX_SETERROR (0); + + return error ? error : LT_DLSTRERROR (UNKNOWN); +} + +static int +lt_dlpath_insertdir (ppath, before, dir) + char **ppath; + char *before; + const char *dir; +{ + int errors = 0; + char *canonical = NULL; + char *argz = NULL; + size_t argz_len = 0; + + assert (ppath); + assert (dir && *dir); + + if (canonicalize_path (dir, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + assert (canonical && *canonical); + + /* If *PPATH is empty, set it to DIR. */ + if (*ppath == NULL) + { + assert (!before); /* BEFORE cannot be set without PPATH. */ + assert (dir); /* Without DIR, don't call this function! */ + + *ppath = lt_estrdup (dir); + if (*ppath == NULL) + ++errors; + + return errors; + } + + assert (ppath && *ppath); + + if (argzize_path (*ppath, &argz, &argz_len) != 0) + { + ++errors; + goto cleanup; + } + + /* Convert BEFORE into an equivalent offset into ARGZ. This only works + if *PPATH is already canonicalized, and hence does not change length + with respect to ARGZ. We canonicalize each entry as it is added to + the search path, and don't call this function with (uncanonicalized) + user paths, so this is a fair assumption. */ + if (before) + { + assert (*ppath <= before); + assert (before - *ppath <= strlen (*ppath)); + + before = before - *ppath + argz; + } + + if (lt_argz_insert (&argz, &argz_len, before, dir) != 0) + { + ++errors; + goto cleanup; + } + + argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); + LT_DLMEM_REASSIGN (*ppath, argz); + + cleanup: + LT_DLFREE (canonical); + LT_DLFREE (argz); + + return errors; +} + +int +lt_dladdsearchdir (search_dir) + const char *search_dir; +{ + int errors = 0; + + if (search_dir && *search_dir) + { + LT_DLMUTEX_LOCK (); + if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0) + ++errors; + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +lt_dlinsertsearchdir (before, search_dir) + const char *before; + const char *search_dir; +{ + int errors = 0; + + if (before) + { + LT_DLMUTEX_LOCK (); + if ((before < user_search_path) + || (before >= user_search_path + LT_STRLEN (user_search_path))) + { + LT_DLMUTEX_UNLOCK (); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION)); + return 1; + } + LT_DLMUTEX_UNLOCK (); + } + + if (search_dir && *search_dir) + { + LT_DLMUTEX_LOCK (); + if (lt_dlpath_insertdir (&user_search_path, + (char *) before, search_dir) != 0) + { + ++errors; + } + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +lt_dlsetsearchpath (search_path) + const char *search_path; +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + LT_DLFREE (user_search_path); + LT_DLMUTEX_UNLOCK (); + + if (!search_path || !LT_STRLEN (search_path)) + { + return errors; + } + + LT_DLMUTEX_LOCK (); + if (canonicalize_path (search_path, &user_search_path) != 0) + ++errors; + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +const char * +lt_dlgetsearchpath () +{ + const char *saved_path; + + LT_DLMUTEX_LOCK (); + saved_path = user_search_path; + LT_DLMUTEX_UNLOCK (); + + return saved_path; +} + +int +lt_dlmakeresident (handle) + lt_dlhandle handle; +{ + int errors = 0; + + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + ++errors; + } + else + { + LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); + } + + return errors; +} + +int +lt_dlisresident (handle) + lt_dlhandle handle; +{ + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return -1; + } + + return LT_DLIS_RESIDENT (handle); +} + + + + +/* --- MODULE INFORMATION --- */ + +const lt_dlinfo * +lt_dlgetinfo (handle) + lt_dlhandle handle; +{ + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return 0; + } + + return &(handle->info); +} + +lt_dlhandle +lt_dlhandle_next (place) + lt_dlhandle place; +{ + return place ? place->next : handles; +} + +int +lt_dlforeach (func, data) + int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data)); + lt_ptr data; +{ + int errors = 0; + lt_dlhandle cur; + + LT_DLMUTEX_LOCK (); + + cur = handles; + while (cur) + { + lt_dlhandle tmp = cur; + + cur = cur->next; + if ((*func) (tmp, data)) + { + ++errors; + break; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +lt_dlcaller_id +lt_dlcaller_register () +{ + static lt_dlcaller_id last_caller_id = 0; + int result; + + LT_DLMUTEX_LOCK (); + result = ++last_caller_id; + LT_DLMUTEX_UNLOCK (); + + return result; +} + +lt_ptr +lt_dlcaller_set_data (key, handle, data) + lt_dlcaller_id key; + lt_dlhandle handle; + lt_ptr data; +{ + int n_elements = 0; + lt_ptr stale = NULL; + int i; + + /* This needs to be locked so that the caller data can be updated + simultaneously by different threads. */ + LT_DLMUTEX_LOCK (); + + if (handle->caller_data) + while (handle->caller_data[n_elements].key) + ++n_elements; + + for (i = 0; i < n_elements; ++i) + { + if (handle->caller_data[i].key == key) + { + stale = handle->caller_data[i].data; + break; + } + } + + /* Ensure that there is enough room in this handle's caller_data + array to accept a new element (and an empty end marker). */ + if (i == n_elements) + { + lt_caller_data *temp + = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements); + + if (!temp) + { + stale = NULL; + goto done; + } + + handle->caller_data = temp; + + /* We only need this if we needed to allocate a new caller_data. */ + handle->caller_data[i].key = key; + handle->caller_data[1+ i].key = 0; + } + + handle->caller_data[i].data = data; + + done: + LT_DLMUTEX_UNLOCK (); + + return stale; +} + +lt_ptr +lt_dlcaller_get_data (key, handle) + lt_dlcaller_id key; + lt_dlhandle handle; +{ + lt_ptr result = (lt_ptr) 0; + + /* This needs to be locked so that the caller data isn't updated by + another thread part way through this function. */ + LT_DLMUTEX_LOCK (); + + /* Locate the index of the element with a matching KEY. */ + { + int i; + for (i = 0; handle->caller_data[i].key; ++i) + { + if (handle->caller_data[i].key == key) + { + result = handle->caller_data[i].data; + break; + } + } + } + + LT_DLMUTEX_UNLOCK (); + + return result; +} + + + +/* --- USER MODULE LOADER API --- */ + + +int +lt_dlloader_add (place, dlloader, loader_name) + lt_dlloader *place; + const struct lt_user_dlloader *dlloader; + const char *loader_name; +{ + int errors = 0; + lt_dlloader *node = NULL, *ptr = NULL; + + if ((dlloader == NULL) /* diagnose null parameters */ + || (dlloader->module_open == NULL) + || (dlloader->module_close == NULL) + || (dlloader->find_sym == NULL)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + return 1; + } + + /* Create a new dlloader node with copies of the user callbacks. */ + node = LT_EMALLOC (lt_dlloader, 1); + if (!node) + return 1; + + node->next = NULL; + node->loader_name = loader_name; + node->sym_prefix = dlloader->sym_prefix; + node->dlloader_exit = dlloader->dlloader_exit; + node->module_open = dlloader->module_open; + node->module_close = dlloader->module_close; + node->find_sym = dlloader->find_sym; + node->dlloader_data = dlloader->dlloader_data; + + LT_DLMUTEX_LOCK (); + if (!loaders) + { + /* If there are no loaders, NODE becomes the list! */ + loaders = node; + } + else if (!place) + { + /* If PLACE is not set, add NODE to the end of the + LOADERS list. */ + for (ptr = loaders; ptr->next; ptr = ptr->next) + { + /*NOWORK*/; + } + + ptr->next = node; + } + else if (loaders == place) + { + /* If PLACE is the first loader, NODE goes first. */ + node->next = place; + loaders = node; + } + else + { + /* Find the node immediately preceding PLACE. */ + for (ptr = loaders; ptr->next != place; ptr = ptr->next) + { + /*NOWORK*/; + } + + if (ptr->next != place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + ++errors; + } + else + { + /* Insert NODE between PTR and PLACE. */ + node->next = place; + ptr->next = node; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +int +lt_dlloader_remove (loader_name) + const char *loader_name; +{ + lt_dlloader *place = lt_dlloader_find (loader_name); + lt_dlhandle handle; + int errors = 0; + + if (!place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + return 1; + } + + LT_DLMUTEX_LOCK (); + + /* Fail if there are any open modules which use this loader. */ + for (handle = handles; handle; handle = handle->next) + { + if (handle->loader == place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER)); + ++errors; + goto done; + } + } + + if (place == loaders) + { + /* PLACE is the first loader in the list. */ + loaders = loaders->next; + } + else + { + /* Find the loader before the one being removed. */ + lt_dlloader *prev; + for (prev = loaders; prev->next; prev = prev->next) + { + if (!strcmp (prev->next->loader_name, loader_name)) + { + break; + } + } + + place = prev->next; + prev->next = prev->next->next; + } + + if (place->dlloader_exit) + { + errors = place->dlloader_exit (place->dlloader_data); + } + + LT_DLFREE (place); + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +lt_dlloader * +lt_dlloader_next (place) + lt_dlloader *place; +{ + lt_dlloader *next; + + LT_DLMUTEX_LOCK (); + next = place ? place->next : loaders; + LT_DLMUTEX_UNLOCK (); + + return next; +} + +const char * +lt_dlloader_name (place) + lt_dlloader *place; +{ + const char *name = NULL; + + if (place) + { + LT_DLMUTEX_LOCK (); + name = place ? place->loader_name : 0; + LT_DLMUTEX_UNLOCK (); + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + } + + return name; +} + +lt_user_data * +lt_dlloader_data (place) + lt_dlloader *place; +{ + lt_user_data *data = NULL; + + if (place) + { + LT_DLMUTEX_LOCK (); + data = place ? &(place->dlloader_data) : 0; + LT_DLMUTEX_UNLOCK (); + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + } + + return data; +} + +lt_dlloader * +lt_dlloader_find (loader_name) + const char *loader_name; +{ + lt_dlloader *place = NULL; + + LT_DLMUTEX_LOCK (); + for (place = loaders; place; place = place->next) + { + if (strcmp (place->loader_name, loader_name) == 0) + { + break; + } + } + LT_DLMUTEX_UNLOCK (); + + return place; +} diff --git a/src/ltdl.h b/src/ltdl.h new file mode 100644 index 00000000..2bbfa302 --- /dev/null +++ b/src/ltdl.h @@ -0,0 +1,361 @@ +/* ltdl.h -- generic dlopen functions + Copyright (C) 1998-2000 Free Software Foundation, Inc. + Originally by Thomas Tanner <tanner@ffii.org> + This file is part of GNU Libtool. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU libtool, you may include it under the same +distribution terms that you use for the rest of that program. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA +*/ + +/* Only include this header file once. */ +#ifndef LTDL_H +#define LTDL_H 1 + +#include <sys/types.h> /* for size_t declaration */ + + +/* --- MACROS FOR PORTABILITY --- */ + + +/* Saves on those hard to debug '\0' typos.... */ +#define LT_EOS_CHAR '\0' + +/* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations, + so that C++ compilers don't mangle their names. Use LTDL_END_C_DECLS at + the end of C declarations. */ +#ifdef __cplusplus +# define LT_BEGIN_C_DECLS extern "C" { +# define LT_END_C_DECLS } +#else +# define LT_BEGIN_C_DECLS /* empty */ +# define LT_END_C_DECLS /* empty */ +#endif + +LT_BEGIN_C_DECLS + + +/* LT_PARAMS is a macro used to wrap function prototypes, so that compilers + that don't understand ANSI C prototypes still work, and ANSI C + compilers can issue warnings about type mismatches. */ +#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus) +# define LT_PARAMS(protos) protos +# define lt_ptr void* +#else +# define LT_PARAMS(protos) () +# define lt_ptr char* +#endif + +/* LT_STMT_START/END are used to create macros which expand to a + a single compound statement in a portable way. */ +#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) +# define LT_STMT_START (void)( +# define LT_STMT_END ) +#else +# if (defined (sun) || defined (__sun__)) +# define LT_STMT_START if (1) +# define LT_STMT_END else (void)0 +# else +# define LT_STMT_START do +# define LT_STMT_END while (0) +# endif +#endif + +/* LT_CONC creates a new concatenated symbol for the compiler + in a portable way. */ +#if defined(__STDC__) || defined(__cplusplus) +# define LT_CONC(s,t) s##t +#else +# define LT_CONC(s,t) s/**/t +#endif + +/* LT_STRLEN can be used safely on NULL pointers. */ +#define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) + + + +/* --- WINDOWS SUPPORT --- */ + + +/* Canonicalise Windows and Cygwin recognition macros. */ +#ifdef __CYGWIN32__ +# ifndef __CYGWIN__ +# define __CYGWIN__ __CYGWIN32__ +# endif +#endif +#if defined(_WIN32) || defined(WIN32) +# ifndef __WINDOWS__ +# ifdef _WIN32 +# define __WINDOWS__ _WIN32 +# else +# ifdef WIN32 +# define __WINDOWS__ WIN32 +# endif +# endif +# endif +#endif + +#ifdef __WINDOWS__ +# ifndef __CYGWIN__ +/* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory + separator when it is set. */ +# define LT_DIRSEP_CHAR '\\' +# define LT_PATHSEP_CHAR ';' +# endif +#endif +#ifndef LT_PATHSEP_CHAR +# define LT_PATHSEP_CHAR ':' +#endif + +/* DLL building support on win32 hosts; mostly to workaround their + ridiculous implementation of data symbol exporting. */ +#ifndef LT_SCOPE +# ifdef __WINDOWS__ +# ifdef DLL_EXPORT /* defined by libtool (if required) */ +# define LT_SCOPE __declspec(dllexport) +# endif +# ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */ +# define LT_SCOPE extern __declspec(dllimport) +# endif +# endif +# ifndef LT_SCOPE /* static linking or !__WINDOWS__ */ +# define LT_SCOPE extern +# endif +#endif + + + + +/* --- DYNAMIC MODULE LOADING API --- */ + + +typedef struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module. */ + +/* Initialisation and finalisation functions for libltdl. */ +extern int lt_dlinit LT_PARAMS((void)); +extern int lt_dlexit LT_PARAMS((void)); + +/* Module search path manipulation. */ +extern int lt_dladdsearchdir LT_PARAMS((const char *search_dir)); +extern int lt_dlinsertsearchdir LT_PARAMS((const char *before, + const char *search_dir)); +extern int lt_dlsetsearchpath LT_PARAMS((const char *search_path)); +extern const char *lt_dlgetsearchpath LT_PARAMS((void)); +extern int lt_dlforeachfile LT_PARAMS(( + const char *search_path, + int (*func) (const char *filename, lt_ptr data), + lt_ptr data)); + +/* Portable libltdl versions of the system dlopen() API. */ +extern lt_dlhandle lt_dlopen LT_PARAMS((const char *filename)); +extern lt_dlhandle lt_dlopenext LT_PARAMS((const char *filename)); +extern lt_ptr lt_dlsym LT_PARAMS((lt_dlhandle handle, + const char *name)); +extern const char *lt_dlerror LT_PARAMS((void)); +extern int lt_dlclose LT_PARAMS((lt_dlhandle handle)); + +/* Module residency management. */ +extern int lt_dlmakeresident LT_PARAMS((lt_dlhandle handle)); +extern int lt_dlisresident LT_PARAMS((lt_dlhandle handle)); + + + + +/* --- MUTEX LOCKING --- */ + + +typedef void lt_dlmutex_lock LT_PARAMS((void)); +typedef void lt_dlmutex_unlock LT_PARAMS((void)); +typedef void lt_dlmutex_seterror LT_PARAMS((const char *errmsg)); +typedef const char *lt_dlmutex_geterror LT_PARAMS((void)); + +extern int lt_dlmutex_register LT_PARAMS((lt_dlmutex_lock *lock, + lt_dlmutex_unlock *unlock, + lt_dlmutex_seterror *seterror, + lt_dlmutex_geterror *geterror)); + + + + +/* --- MEMORY HANDLING --- */ + + +/* By default, the realloc function pointer is set to our internal + realloc implementation which iself uses lt_dlmalloc and lt_dlfree. + libltdl relies on a featureful realloc, but if you are sure yours + has the right semantics then you can assign it directly. Generally, + it is safe to assign just a malloc() and a free() function. */ +LT_SCOPE lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)); +LT_SCOPE lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size)); +LT_SCOPE void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)); + + + + +/* --- PRELOADED MODULE SUPPORT --- */ + + +/* A preopened symbol. Arrays of this type comprise the exported + symbols for a dlpreopened module. */ +typedef struct { + const char *name; + lt_ptr address; +} lt_dlsymlist; + +extern int lt_dlpreload LT_PARAMS((const lt_dlsymlist *preloaded)); +extern int lt_dlpreload_default + LT_PARAMS((const lt_dlsymlist *preloaded)); + +#define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \ + extern const lt_dlsymlist lt_preloaded_symbols[]; \ + lt_dlpreload_default(lt_preloaded_symbols); \ + }LT_STMT_END + + + + +/* --- MODULE INFORMATION --- */ + + +/* Read only information pertaining to a loaded module. */ +typedef struct { + char *filename; /* file name */ + char *name; /* module name */ + int ref_count; /* number of times lt_dlopened minus + number of times lt_dlclosed. */ +} lt_dlinfo; + +extern const lt_dlinfo *lt_dlgetinfo LT_PARAMS((lt_dlhandle handle)); +extern lt_dlhandle lt_dlhandle_next LT_PARAMS((lt_dlhandle place)); +extern int lt_dlforeach LT_PARAMS(( + int (*func) (lt_dlhandle handle, lt_ptr data), + lt_ptr data)); + +/* Associating user data with loaded modules. */ +typedef unsigned lt_dlcaller_id; + +extern lt_dlcaller_id lt_dlcaller_register LT_PARAMS((void)); +extern lt_ptr lt_dlcaller_set_data LT_PARAMS((lt_dlcaller_id key, + lt_dlhandle handle, + lt_ptr data)); +extern lt_ptr lt_dlcaller_get_data LT_PARAMS((lt_dlcaller_id key, + lt_dlhandle handle)); + + + +/* --- USER MODULE LOADER API --- */ + + +typedef struct lt_dlloader lt_dlloader; +typedef lt_ptr lt_user_data; +typedef lt_ptr lt_module; + +/* Function pointer types for creating user defined module loaders. */ +typedef lt_module lt_module_open LT_PARAMS((lt_user_data loader_data, + const char *filename)); +typedef int lt_module_close LT_PARAMS((lt_user_data loader_data, + lt_module handle)); +typedef lt_ptr lt_find_sym LT_PARAMS((lt_user_data loader_data, + lt_module handle, + const char *symbol)); +typedef int lt_dlloader_exit LT_PARAMS((lt_user_data loader_data)); + +struct lt_user_dlloader { + const char *sym_prefix; + lt_module_open *module_open; + lt_module_close *module_close; + lt_find_sym *find_sym; + lt_dlloader_exit *dlloader_exit; + lt_user_data dlloader_data; +}; + +extern lt_dlloader *lt_dlloader_next LT_PARAMS((lt_dlloader *place)); +extern lt_dlloader *lt_dlloader_find LT_PARAMS(( + const char *loader_name)); +extern const char *lt_dlloader_name LT_PARAMS((lt_dlloader *place)); +extern lt_user_data *lt_dlloader_data LT_PARAMS((lt_dlloader *place)); +extern int lt_dlloader_add LT_PARAMS((lt_dlloader *place, + const struct lt_user_dlloader *dlloader, + const char *loader_name)); +extern int lt_dlloader_remove LT_PARAMS(( + const char *loader_name)); + + + +/* --- ERROR MESSAGE HANDLING --- */ + + +/* Defining error strings alongside their symbolic names in a macro in + this way allows us to expand the macro in different contexts with + confidence that the enumeration of symbolic names will map correctly + onto the table of error strings. */ +#define lt_dlerror_table \ + LT_ERROR(UNKNOWN, "unknown error") \ + LT_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available") \ + LT_ERROR(INVALID_LOADER, "invalid loader") \ + LT_ERROR(INIT_LOADER, "loader initialization failed") \ + LT_ERROR(REMOVE_LOADER, "loader removal failed") \ + LT_ERROR(FILE_NOT_FOUND, "file not found") \ + LT_ERROR(DEPLIB_NOT_FOUND, "dependency library not found") \ + LT_ERROR(NO_SYMBOLS, "no symbols defined") \ + LT_ERROR(CANNOT_OPEN, "can't open the module") \ + LT_ERROR(CANNOT_CLOSE, "can't close the module") \ + LT_ERROR(SYMBOL_NOT_FOUND, "symbol not found") \ + LT_ERROR(NO_MEMORY, "not enough memory") \ + LT_ERROR(INVALID_HANDLE, "invalid module handle") \ + LT_ERROR(BUFFER_OVERFLOW, "internal buffer overflow") \ + LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \ + LT_ERROR(SHUTDOWN, "library already shutdown") \ + LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \ + LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration") \ + LT_ERROR(INVALID_POSITION, "invalid search path insert position") + +/* Enumerate the symbolic error names. */ +enum { +#define LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name), + lt_dlerror_table +#undef LT_ERROR + + LT_ERROR_MAX +}; + +/* These functions are only useful from inside custom module loaders. */ +extern int lt_dladderror LT_PARAMS((const char *diagnostic)); +extern int lt_dlseterror LT_PARAMS((int errorcode)); + + + + +/* --- SOURCE COMPATIBILITY WITH OLD LIBLTDL --- */ + + +#ifdef LT_NON_POSIX_NAMESPACE +# define lt_ptr_t lt_ptr +# define lt_module_t lt_module +# define lt_module_open_t lt_module_open +# define lt_module_close_t lt_module_close +# define lt_find_sym_t lt_find_sym +# define lt_dlloader_exit_t lt_dlloader_exit +# define lt_dlloader_t lt_dlloader +# define lt_dlloader_data_t lt_user_data +#endif + +LT_END_C_DECLS + +#endif /* !LTDL_H */ diff --git a/src/nss/Makefile.am b/src/nss/Makefile.am index 749c98657..1e635848 100644 --- a/src/nss/Makefile.am +++ b/src/nss/Makefile.am @@ -6,6 +6,7 @@ EXTRA_DIST = \ $(NULL) INCLUDES = \ + -DPACKAGE=\"@PACKAGE@\" \ -I$(top_srcdir) \ -I$(top_srcdir)/include \ $(XMLSEC_DEFINES) \ diff --git a/src/nss/app.c b/src/nss/app.c index 6720bb28..4b20da7c 100644 --- a/src/nss/app.c +++ b/src/nss/app.c @@ -1061,3 +1061,15 @@ xmlSecNssAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filename, xm return(0); } +/** + * xmlSecNssAppGetDefaultPwdCallback: + * + * Gets default password callback. + * + * Returns default password callback. + */ +void* +xmlSecNssAppGetDefaultPwdCallback(void) { + return(NULL); +} + diff --git a/src/nss/crypto.c b/src/nss/crypto.c index bb37284f..a3042eb3 100644 --- a/src/nss/crypto.c +++ b/src/nss/crypto.c @@ -21,12 +21,123 @@ #include <xmlsec/keysmngr.h> #include <xmlsec/transforms.h> #include <xmlsec/errors.h> +#include <xmlsec/dl.h> +#include <xmlsec/private.h> +#include <xmlsec/nss/app.h> #include <xmlsec/nss/crypto.h> #include <xmlsec/nss/x509.h> -static int xmlSecNssKeysInit (void); -static int xmlSecNssTransformsInit (void); +static xmlSecCryptoDLFunctionsPtr gXmlSecNssFunctions = NULL; + +xmlSecCryptoDLFunctionsPtr +xmlSecCryptoGetFunctions_nss(void) { + static xmlSecCryptoDLFunctions functions; + + if(gXmlSecNssFunctions != NULL) { + return(gXmlSecNssFunctions); + } + + memset(&functions, 0, sizeof(functions)); + gXmlSecNssFunctions = &functions; + + /** + * Crypto Init/shutdown + */ + gXmlSecNssFunctions->cryptoInit = xmlSecNssInit; + gXmlSecNssFunctions->cryptoShutdown = xmlSecNssShutdown; + gXmlSecNssFunctions->cryptoKeysMngrInit = xmlSecNssKeysMngrInit; + + /** + * Key data ids + */ +#ifndef XMLSEC_NO_AES + gXmlSecNssFunctions->keyDataAesGetKlass = xmlSecNssKeyDataAesGetKlass; +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES + gXmlSecNssFunctions->keyDataDesGetKlass = xmlSecNssKeyDataDesGetKlass; +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_DSA + gXmlSecNssFunctions->keyDataDsaGetKlass = xmlSecNssKeyDataDsaGetKlass; +#endif /* XMLSEC_NO_DSA */ + +#ifndef XMLSEC_NO_HMAC + gXmlSecNssFunctions->keyDataHmacGetKlass = xmlSecNssKeyDataHmacGetKlass; +#endif /* XMLSEC_NO_HMAC */ + +#ifndef XMLSEC_NO_RSA + gXmlSecNssFunctions->keyDataRsaGetKlass = xmlSecNssKeyDataRsaGetKlass; +#endif /* XMLSEC_NO_RSA */ + +#ifndef XMLSEC_NO_X509 + gXmlSecNssFunctions->keyDataX509GetKlass = xmlSecNssKeyDataX509GetKlass; + gXmlSecNssFunctions->keyDataRawX509CertGetKlass = xmlSecNssKeyDataRawX509CertGetKlass; +#endif /* XMLSEC_NO_X509 */ + + /** + * Key data store ids + */ +#ifndef XMLSEC_NO_X509 + gXmlSecNssFunctions->x509StoreGetKlass = xmlSecNssX509StoreGetKlass; +#endif /* XMLSEC_NO_X509 */ + + /** + * Crypto transforms ids + */ +#ifndef XMLSEC_NO_AES + gXmlSecNssFunctions->transformAes128CbcGetKlass = xmlSecNssTransformAes128CbcGetKlass; + gXmlSecNssFunctions->transformAes192CbcGetKlass = xmlSecNssTransformAes192CbcGetKlass; + gXmlSecNssFunctions->transformAes256CbcGetKlass = xmlSecNssTransformAes256CbcGetKlass; + gXmlSecNssFunctions->transformKWAes128GetKlass = xmlSecNssTransformKWAes128GetKlass; + gXmlSecNssFunctions->transformKWAes192GetKlass = xmlSecNssTransformKWAes192GetKlass; + gXmlSecNssFunctions->transformKWAes256GetKlass = xmlSecNssTransformKWAes256GetKlass; +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES + gXmlSecNssFunctions->transformDes3CbcGetKlass = xmlSecNssTransformDes3CbcGetKlass; + gXmlSecNssFunctions->transformKWDes3GetKlass = xmlSecNssTransformKWDes3GetKlass; +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_DSA + gXmlSecNssFunctions->transformDsaSha1GetKlass = xmlSecNssTransformDsaSha1GetKlass; +#endif /* XMLSEC_NO_DSA */ + +#ifndef XMLSEC_NO_HMAC + gXmlSecNssFunctions->transformHmacSha1GetKlass = xmlSecNssTransformHmacSha1GetKlass; + gXmlSecNssFunctions->transformHmacRipemd160GetKlass = xmlSecNssTransformHmacRipemd160GetKlass; + gXmlSecNssFunctions->transformHmacMd5GetKlass = xmlSecNssTransformHmacMd5GetKlass; +#endif /* XMLSEC_NO_HMAC */ + +#ifndef XMLSEC_NO_RSA + gXmlSecNssFunctions->transformRsaSha1GetKlass = xmlSecNssTransformRsaSha1GetKlass; + gXmlSecNssFunctions->transformRsaPkcs1GetKlass = xmlSecNssTransformRsaPkcs1GetKlass; +#endif /* XMLSEC_NO_RSA */ + +#ifndef XMLSEC_NO_SHA1 + gXmlSecNssFunctions->transformSha1GetKlass = xmlSecNssTransformSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + + /** + * High level routines form xmlsec command line utility + */ + gXmlSecNssFunctions->cryptoAppInit = xmlSecNssAppInit; + gXmlSecNssFunctions->cryptoAppShutdown = xmlSecNssAppShutdown; + gXmlSecNssFunctions->cryptoAppDefaultKeysMngrInit = xmlSecNssAppDefaultKeysMngrInit; + gXmlSecNssFunctions->cryptoAppDefaultKeysMngrAdoptKey = xmlSecNssAppDefaultKeysMngrAdoptKey; + gXmlSecNssFunctions->cryptoAppDefaultKeysMngrLoad = xmlSecNssAppDefaultKeysMngrLoad; + gXmlSecNssFunctions->cryptoAppDefaultKeysMngrSave = xmlSecNssAppDefaultKeysMngrSave; +#ifndef XMLSEC_NO_X509 + gXmlSecNssFunctions->cryptoAppKeysMngrCertLoad = xmlSecNssAppKeysMngrCertLoad; + gXmlSecNssFunctions->cryptoAppPkcs12Load = xmlSecNssAppPkcs12Load; + gXmlSecNssFunctions->cryptoAppKeyCertLoad = xmlSecNssAppKeyCertLoad; +#endif /* XMLSEC_NO_X509 */ + gXmlSecNssFunctions->cryptoAppKeyLoad = xmlSecNssAppKeyLoad; + gXmlSecNssFunctions->cryptoAppDefaultPwdCallback = (void*)xmlSecNssAppGetDefaultPwdCallback; + + return(gXmlSecNssFunctions); +} /** * xmlSecNssInit: @@ -37,18 +148,10 @@ static int xmlSecNssTransformsInit (void); */ int xmlSecNssInit (void) { - if(xmlSecNssKeysInit() < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecNssKeysInit", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecNssTransformsInit() < 0) { + if(xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms(xmlSecCryptoGetFunctions_nss()) < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, - "xmlSecNssTransformsInit", + "xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); @@ -155,234 +258,4 @@ xmlSecNssGenerateRandom(xmlSecBufferPtr buffer, xmlSecSize size) { } -static int -xmlSecNssKeysInit(void) { - -#ifndef XMLSEC_NO_AES - if(xmlSecKeyDataIdsRegister(xmlSecNssKeyDataAesId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecNssKeyDataAesId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_AES */ - -#ifndef XMLSEC_NO_DES - if(xmlSecKeyDataIdsRegister(xmlSecNssKeyDataDesId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecNssKeyDataDesId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_DES */ - -#ifndef XMLSEC_NO_DSA - if(xmlSecKeyDataIdsRegister(xmlSecNssKeyDataDsaId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecNssKeyDataDsaId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_DSA */ - -#ifndef XMLSEC_NO_HMAC - if(xmlSecKeyDataIdsRegister(xmlSecNssKeyDataHmacId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecNssKeyDataHmacId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_HMAC */ - -#ifndef XMLSEC_NO_RSA - if(xmlSecKeyDataIdsRegister(xmlSecNssKeyDataRsaId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecNssKeyDataRsaId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_RSA */ - -#ifndef XMLSEC_NO_X509 - if(xmlSecKeyDataIdsRegister(xmlSecNssKeyDataX509Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecNssKeyDataX509Id)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - if(xmlSecKeyDataIdsRegister(xmlSecNssKeyDataRawX509CertId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecNssKeyDataRawX509CertId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_X509 */ - - return(0); -} - -static int -xmlSecNssTransformsInit(void) { -#ifndef XMLSEC_NO_SHA1 - if(xmlSecTransformIdsRegister(xmlSecNssTransformSha1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformSha1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_SHA1 */ - -#ifndef XMLSEC_NO_HMAC - if(xmlSecTransformIdsRegister(xmlSecNssTransformHmacSha1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformHmacSha1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecNssTransformHmacRipemd160Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformHmacRipemd160Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecNssTransformHmacMd5Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformHmacMd5Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_HMAC */ - -#ifndef XMLSEC_NO_DSA - if(xmlSecTransformIdsRegister(xmlSecNssTransformDsaSha1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformDsaSha1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_DSA */ - -#ifndef XMLSEC_NO_RSA - if(xmlSecTransformIdsRegister(xmlSecNssTransformRsaSha1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformRsaSha1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - /* This is not supported by NSS yet */ -#if 0 - if(xmlSecTransformIdsRegister(xmlSecNssTransformRsaPkcs1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformRsaPkcs1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* 0 */ - -#endif /* XMLSEC_NO_RSA */ - -#ifndef XMLSEC_NO_DES - if(xmlSecTransformIdsRegister(xmlSecNssTransformDes3CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformDes3CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - if(xmlSecTransformIdsRegister(xmlSecNssTransformKWDes3Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformKWDes3Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_DES */ - -#ifndef XMLSEC_NO_AES - if(xmlSecTransformIdsRegister(xmlSecNssTransformAes128CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformAes128CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecNssTransformAes192CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformAes192CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecNssTransformAes256CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformAes256CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - if(xmlSecTransformIdsRegister(xmlSecNssTransformKWAes128Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformKWAes128Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecNssTransformKWAes192Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformKWAes192Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecNssTransformKWAes256Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecNssTransformKWAes256Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_AES */ - - return(0); -} - diff --git a/src/nss/globals.h b/src/nss/globals.h index 0f2bf445..272a27b8 100644 --- a/src/nss/globals.h +++ b/src/nss/globals.h @@ -11,8 +11,14 @@ #ifndef __XMLSEC_GLOBALS_H__ #define __XMLSEC_GLOBALS_H__ +/** + * Use autoconf defines if present. + */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif /* HAVE_CONFIG_H */ #define IN_XMLSEC_CRYPTO +#define XMLSEC_PRIVATE #endif /* ! __XMLSEC_GLOBALS_H__ */ diff --git a/src/openssl/Makefile.am b/src/openssl/Makefile.am index 3869ccfe..763aaa4f 100644 --- a/src/openssl/Makefile.am +++ b/src/openssl/Makefile.am @@ -5,6 +5,7 @@ EXTRA_DIST = \ $(NULL) INCLUDES = \ + -DPACKAGE=\"@PACKAGE@\" \ -I$(top_srcdir) \ -I$(top_srcdir)/include \ $(XMLSEC_DEFINES) \ diff --git a/src/openssl/app.c b/src/openssl/app.c index 73f8f9ac..9bb21ab7 100644 --- a/src/openssl/app.c +++ b/src/openssl/app.c @@ -9,6 +9,10 @@ #include "globals.h" #include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#include <libxml/tree.h> #include <openssl/evp.h> #include <openssl/rand.h> @@ -27,6 +31,11 @@ static int xmlSecOpenSSLAppLoadRANDFile (const char *file); static int xmlSecOpenSSLAppSaveRANDFile (const char *file); +static int xmlSecOpenSSLDefaultPasswordCallback (char *buf, int bufsiz, int verify, void *userdata); + +#if defined(_MSC_VER) +#define snprintf _snprintf +#endif /** * xmlSecOpenSSLAppInit: @@ -1285,3 +1294,90 @@ xmlSecOpenSSLAppSaveRANDFile(const char *file) { return 1; } +/** + * xmlSecOpenSSLAppGetDefaultPwdCallback: + * + * Gets default password callback. + * + * Returns default password callback. + */ +void* +xmlSecOpenSSLAppGetDefaultPwdCallback(void) { + return((void*)xmlSecOpenSSLDefaultPasswordCallback); +} + +static int +xmlSecOpenSSLDefaultPasswordCallback(char *buf, int bufsize, int verify, void *userdata) { + char* filename = (char*)userdata; + char* buf2; + char prompt[2048]; + int i, ret; + + xmlSecAssert2(buf != NULL, -1); + + /* try 3 times */ + for(i = 0; i < 3; i++) { + if(filename != NULL) { + snprintf(prompt, sizeof(prompt), "Enter password for \"%s\" file: ", filename); + } else { + snprintf(prompt, sizeof(prompt), "Enter password: "); + } + ret = EVP_read_pw_string(buf, bufsize, prompt, 0); + if(ret != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "EVP_read_pw_string", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + /* if we don't need to verify password then we are done */ + if(verify == 0) { + return(0); + } + + if(filename != NULL) { + snprintf(prompt, sizeof(prompt), "Enter password for \"%s\" file again: ", filename); + } else { + snprintf(prompt, sizeof(prompt), "Enter password again: "); + } + + buf2 = (char*)xmlMalloc(bufsize); + if(buf2 == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", bufsize); + return(-1); + } + ret = EVP_read_pw_string(buf2, bufsize, prompt, 0); + if(ret != 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "EVP_read_pw_string", + XMLSEC_ERRORS_R_CRYPTO_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + memset(buf2, 0, bufsize); + xmlFree(buf2); + return(-1); + } + + /* check if passwords match */ + if(strcmp(buf, buf2) == 0) { + memset(buf2, 0, bufsize); + xmlFree(buf2); + return(-1); + } + + /* try again */ + memset(buf2, 0, bufsize); + xmlFree(buf2); + } + + return(-1); +} + + + diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c index 983d9011..54f18f70 100644 --- a/src/openssl/crypto.c +++ b/src/openssl/crypto.c @@ -18,13 +18,134 @@ #include <xmlsec/keysmngr.h> #include <xmlsec/transforms.h> #include <xmlsec/errors.h> +#include <xmlsec/dl.h> +#include <xmlsec/private.h> +#include <xmlsec/openssl/app.h> #include <xmlsec/openssl/crypto.h> #include <xmlsec/openssl/x509.h> static int xmlSecOpenSSLErrorsInit (void); -static int xmlSecOpenSSLKeysInit (void); -static int xmlSecOpenSSLTransformsInit (void); + +static xmlSecCryptoDLFunctionsPtr gXmlSecOpenSSLFunctions = NULL; + +xmlSecCryptoDLFunctionsPtr +xmlSecCryptoGetFunctions_openssl(void) { + static xmlSecCryptoDLFunctions functions; + + if(gXmlSecOpenSSLFunctions != NULL) { + return(gXmlSecOpenSSLFunctions); + } + + memset(&functions, 0, sizeof(functions)); + gXmlSecOpenSSLFunctions = &functions; + + /** + * Crypto Init/shutdown + */ + gXmlSecOpenSSLFunctions->cryptoInit = xmlSecOpenSSLInit; + gXmlSecOpenSSLFunctions->cryptoShutdown = xmlSecOpenSSLShutdown; + gXmlSecOpenSSLFunctions->cryptoKeysMngrInit = xmlSecOpenSSLKeysMngrInit; + + /** + * Key data ids + */ +#ifndef XMLSEC_NO_AES +#ifndef XMLSEC_OPENSSL_096 + gXmlSecOpenSSLFunctions->keyDataAesGetKlass = xmlSecOpenSSLKeyDataAesGetKlass; +#endif /* XMLSEC_OPENSSL_096 */ +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES + gXmlSecOpenSSLFunctions->keyDataDesGetKlass = xmlSecOpenSSLKeyDataDesGetKlass; +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_DSA + gXmlSecOpenSSLFunctions->keyDataDsaGetKlass = xmlSecOpenSSLKeyDataDsaGetKlass; +#endif /* XMLSEC_NO_DSA */ + +#ifndef XMLSEC_NO_HMAC + gXmlSecOpenSSLFunctions->keyDataHmacGetKlass = xmlSecOpenSSLKeyDataHmacGetKlass; +#endif /* XMLSEC_NO_HMAC */ + +#ifndef XMLSEC_NO_RSA + gXmlSecOpenSSLFunctions->keyDataRsaGetKlass = xmlSecOpenSSLKeyDataRsaGetKlass; +#endif /* XMLSEC_NO_RSA */ + +#ifndef XMLSEC_NO_X509 + gXmlSecOpenSSLFunctions->keyDataX509GetKlass = xmlSecOpenSSLKeyDataX509GetKlass; + gXmlSecOpenSSLFunctions->keyDataRawX509CertGetKlass = xmlSecOpenSSLKeyDataRawX509CertGetKlass; +#endif /* XMLSEC_NO_X509 */ + + /** + * Key data store ids + */ +#ifndef XMLSEC_NO_X509 + gXmlSecOpenSSLFunctions->x509StoreGetKlass = xmlSecOpenSSLX509StoreGetKlass; +#endif /* XMLSEC_NO_X509 */ + + /** + * Crypto transforms ids + */ +#ifndef XMLSEC_NO_AES +#ifndef XMLSEC_OPENSSL_096 + gXmlSecOpenSSLFunctions->transformAes128CbcGetKlass = xmlSecOpenSSLTransformAes128CbcGetKlass; + gXmlSecOpenSSLFunctions->transformAes192CbcGetKlass = xmlSecOpenSSLTransformAes192CbcGetKlass; + gXmlSecOpenSSLFunctions->transformAes256CbcGetKlass = xmlSecOpenSSLTransformAes256CbcGetKlass; + gXmlSecOpenSSLFunctions->transformKWAes128GetKlass = xmlSecOpenSSLTransformKWAes128GetKlass; + gXmlSecOpenSSLFunctions->transformKWAes192GetKlass = xmlSecOpenSSLTransformKWAes192GetKlass; + gXmlSecOpenSSLFunctions->transformKWAes256GetKlass = xmlSecOpenSSLTransformKWAes256GetKlass; +#endif /* XMLSEC_OPENSSL_096 */ +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES + gXmlSecOpenSSLFunctions->transformDes3CbcGetKlass = xmlSecOpenSSLTransformDes3CbcGetKlass; + gXmlSecOpenSSLFunctions->transformKWDes3GetKlass = xmlSecOpenSSLTransformKWDes3GetKlass; +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_DSA + gXmlSecOpenSSLFunctions->transformDsaSha1GetKlass = xmlSecOpenSSLTransformDsaSha1GetKlass; +#endif /* XMLSEC_NO_DSA */ + +#ifndef XMLSEC_NO_HMAC + gXmlSecOpenSSLFunctions->transformHmacSha1GetKlass = xmlSecOpenSSLTransformHmacSha1GetKlass; + gXmlSecOpenSSLFunctions->transformHmacRipemd160GetKlass = xmlSecOpenSSLTransformHmacRipemd160GetKlass; + gXmlSecOpenSSLFunctions->transformHmacMd5GetKlass = xmlSecOpenSSLTransformHmacMd5GetKlass; +#endif /* XMLSEC_NO_HMAC */ + +#ifndef XMLSEC_NO_RIPEMD160 + gXmlSecOpenSSLFunctions->transformRipemd160GetKlass = xmlSecOpenSSLTransformRipemd160GetKlass; +#endif /* XMLSEC_NO_RIPEMD160 */ + +#ifndef XMLSEC_NO_RSA + gXmlSecOpenSSLFunctions->transformRsaSha1GetKlass = xmlSecOpenSSLTransformRsaSha1GetKlass; + gXmlSecOpenSSLFunctions->transformRsaPkcs1GetKlass = xmlSecOpenSSLTransformRsaPkcs1GetKlass; + gXmlSecOpenSSLFunctions->transformRsaOaepGetKlass = xmlSecOpenSSLTransformRsaOaepGetKlass; +#endif /* XMLSEC_NO_RSA */ + +#ifndef XMLSEC_NO_SHA1 + gXmlSecOpenSSLFunctions->transformSha1GetKlass = xmlSecOpenSSLTransformSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + + /** + * High level routines form xmlsec command line utility + */ + gXmlSecOpenSSLFunctions->cryptoAppInit = xmlSecOpenSSLAppInit; + gXmlSecOpenSSLFunctions->cryptoAppShutdown = xmlSecOpenSSLAppShutdown; + gXmlSecOpenSSLFunctions->cryptoAppDefaultKeysMngrInit = xmlSecOpenSSLAppDefaultKeysMngrInit; + gXmlSecOpenSSLFunctions->cryptoAppDefaultKeysMngrAdoptKey = xmlSecOpenSSLAppDefaultKeysMngrAdoptKey; + gXmlSecOpenSSLFunctions->cryptoAppDefaultKeysMngrLoad = xmlSecOpenSSLAppDefaultKeysMngrLoad; + gXmlSecOpenSSLFunctions->cryptoAppDefaultKeysMngrSave = xmlSecOpenSSLAppDefaultKeysMngrSave; +#ifndef XMLSEC_NO_X509 + gXmlSecOpenSSLFunctions->cryptoAppKeysMngrCertLoad = xmlSecOpenSSLAppKeysMngrCertLoad; + gXmlSecOpenSSLFunctions->cryptoAppPkcs12Load = (xmlSecCryptoAppPkcs12LoadMethod)xmlSecOpenSSLAppPkcs12Load; /* todo: to fix this we need to change xmlSecOpenSSLAppPkcs12Load signature */ + gXmlSecOpenSSLFunctions->cryptoAppKeyCertLoad = xmlSecOpenSSLAppKeyCertLoad; +#endif /* XMLSEC_NO_X509 */ + gXmlSecOpenSSLFunctions->cryptoAppKeyLoad = (xmlSecCryptoAppKeyLoadMethod)xmlSecOpenSSLAppKeyLoad; /* todo: to fix this we need to fix the xmlSecOpenSSLAppKeyLoad signature */ + gXmlSecOpenSSLFunctions->cryptoAppDefaultPwdCallback = (void*)xmlSecOpenSSLAppGetDefaultPwdCallback; + + return(gXmlSecOpenSSLFunctions); +} /** * xmlSecOpenSSLInit: @@ -43,18 +164,10 @@ xmlSecOpenSSLInit (void) { XMLSEC_ERRORS_NO_MESSAGE); return(-1); } - if(xmlSecOpenSSLKeysInit() < 0) { + if(xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms(xmlSecCryptoGetFunctions_openssl()) < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, - "xmlSecOpenSSLKeysInit", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecOpenSSLTransformsInit() < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecOpenSSLTransformsInit", + "xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); @@ -215,249 +328,3 @@ xmlSecOpenSSLErrorsInit(void) { return(0); } -static int -xmlSecOpenSSLKeysInit(void) { -#ifndef XMLSEC_NO_AES -#ifndef XMLSEC_OPENSSL_096 - if(xmlSecKeyDataIdsRegister(xmlSecOpenSSLKeyDataAesId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecOpenSSLKeyDataAesId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_OPENSSL_096 */ -#endif /* XMLSEC_NO_AES */ - -#ifndef XMLSEC_NO_DES - if(xmlSecKeyDataIdsRegister(xmlSecOpenSSLKeyDataDesId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecOpenSSLKeyDataDesId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_DES */ - -#ifndef XMLSEC_NO_DSA - if(xmlSecKeyDataIdsRegister(xmlSecOpenSSLKeyDataDsaId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecOpenSSLKeyDataDsaId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_DSA */ - -#ifndef XMLSEC_NO_HMAC - if(xmlSecKeyDataIdsRegister(xmlSecOpenSSLKeyDataHmacId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecOpenSSLKeyDataHmacId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_HMAC */ - -#ifndef XMLSEC_NO_RSA - if(xmlSecKeyDataIdsRegister(xmlSecOpenSSLKeyDataRsaId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecOpenSSLKeyDataRsaId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_RSA */ - -#ifndef XMLSEC_NO_X509 - if(xmlSecKeyDataIdsRegister(xmlSecOpenSSLKeyDataX509Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecOpenSSLKeyDataX509Id)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - if(xmlSecKeyDataIdsRegister(xmlSecOpenSSLKeyDataRawX509CertId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(xmlSecOpenSSLKeyDataRawX509CertId)), - "xmlSecKeyDataIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_X509 */ - - return(0); -} - -static int -xmlSecOpenSSLTransformsInit(void) { -#ifndef XMLSEC_NO_SHA1 - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformSha1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformSha1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_SHA1 */ - -#ifndef XMLSEC_NO_RIPEMD160 - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformRipemd160Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformRipemd160Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_RIPEMD160 */ - -#ifndef XMLSEC_NO_HMAC - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformHmacSha1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformHmacSha1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformHmacRipemd160Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformHmacRipemd160Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformHmacMd5Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformHmacMd5Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_HMAC */ - -#ifndef XMLSEC_NO_DSA - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformDsaSha1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformDsaSha1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_DSA */ - -#ifndef XMLSEC_NO_RSA - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformRsaSha1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformRsaSha1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformRsaPkcs1Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformRsaPkcs1Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformRsaOaepId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformRsaOaepId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_RSA */ - -#ifndef XMLSEC_NO_DES - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformDes3CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformDes3CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformKWDes3Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformKWDes3Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_NO_DES */ - -#ifndef XMLSEC_NO_AES -#ifndef XMLSEC_OPENSSL_096 - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformAes128CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformAes128CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformAes192CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformAes192CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformAes256CbcId) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformAes256CbcId)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformKWAes128Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformKWAes128Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformKWAes192Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformKWAes192Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } - if(xmlSecTransformIdsRegister(xmlSecOpenSSLTransformKWAes256Id) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecOpenSSLTransformKWAes256Id)), - "xmlSecTransformIdsRegister", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } -#endif /* XMLSEC_OPENSSL_096 */ -#endif /* XMLSEC_NO_AES */ - - return(0); -} diff --git a/src/openssl/globals.h b/src/openssl/globals.h index 0f2bf445..272a27b8 100644 --- a/src/openssl/globals.h +++ b/src/openssl/globals.h @@ -11,8 +11,14 @@ #ifndef __XMLSEC_GLOBALS_H__ #define __XMLSEC_GLOBALS_H__ +/** + * Use autoconf defines if present. + */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif /* HAVE_CONFIG_H */ #define IN_XMLSEC_CRYPTO +#define XMLSEC_PRIVATE #endif /* ! __XMLSEC_GLOBALS_H__ */ diff --git a/src/skeleton/Makefile.am b/src/skeleton/Makefile.am index e4915aea..692ccd64 100644 --- a/src/skeleton/Makefile.am +++ b/src/skeleton/Makefile.am @@ -5,6 +5,7 @@ EXTRA_DIST = \ $(NULL) INCLUDES = \ + -DPACKAGE=\"@PACKAGE@\" \ -I$(top_srcdir) \ -I$(top_srcdir)/include \ $(XMLSEC_DEFINES) \ diff --git a/src/skeleton/app.c b/src/skeleton/app.c index 0698c73b..820a2a83 100644 --- a/src/skeleton/app.c +++ b/src/skeleton/app.c @@ -175,30 +175,6 @@ xmlSecSkeletonAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, const char *filename, return(-1); } -/** - * xmlSecSkeletonAppKeysMngrAddCertsPath: - * @mngr: the keys manager. - * @path: the path to trusted certificates. - * - * Reads cert from @path and adds to the list of trusted certificates - * (not implemented yet). - * - * Returns 0 on success or a negative value otherwise. - */ -int -xmlSecSkeletonAppKeysMngrAddCertsPath(xmlSecKeysMngrPtr mngr, const char *path) { - xmlSecAssert2(mngr != NULL, -1); - xmlSecAssert2(path != NULL, -1); - - /* TODO: load trusted cert from path */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecSkeletonAppKeysMngrAddCertsPath", - XMLSEC_ERRORS_R_NOT_IMPLEMENTED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); -} - #endif /* XMLSEC_NO_X509 */ /** @@ -396,3 +372,16 @@ xmlSecSkeletonAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filenam return(0); } +/** + * xmlSecSkeletonAppGetDefaultPwdCallback: + * + * Gets default password callback. + * + * Returns default password callback. + */ +void* +xmlSecSkeletonAppGetDefaultPwdCallback(void) { + /* TODO */ + return(NULL); +} + diff --git a/src/skeleton/crypto.c b/src/skeleton/crypto.c index cdab7fa8..aa1a2e5a 100644 --- a/src/skeleton/crypto.c +++ b/src/skeleton/crypto.c @@ -16,11 +16,128 @@ #include <xmlsec/keys.h> #include <xmlsec/transforms.h> #include <xmlsec/errors.h> +#include <xmlsec/dl.h> +#include <xmlsec/private.h> +#include <xmlsec/skeleton/app.h> #include <xmlsec/skeleton/crypto.h> -static int xmlSecSkeletonKeysInit (void); -static int xmlSecSkeletonTransformsInit (void); +static xmlSecCryptoDLFunctionsPtr gXmlSecSkeletonFunctions = NULL; + +xmlSecCryptoDLFunctionsPtr +xmlSecCryptoGetFunctions_skeleton(void) { + static xmlSecCryptoDLFunctions functions; + + if(gXmlSecSkeletonFunctions != NULL) { + return(gXmlSecSkeletonFunctions); + } + + memset(&functions, 0, sizeof(functions)); + gXmlSecSkeletonFunctions = &functions; + + /** + * Crypto Init/shutdown + */ + gXmlSecSkeletonFunctions->cryptoInit = xmlSecSkeletonInit; + gXmlSecSkeletonFunctions->cryptoShutdown = xmlSecSkeletonShutdown; + gXmlSecSkeletonFunctions->cryptoKeysMngrInit = xmlSecSkeletonKeysMngrInit; + + /** + * Key data ids + */ +#ifndef XMLSEC_NO_AES + gXmlSecSkeletonFunctions->keyDataAesGetKlass = xmlSecSkeletonKeyDataAesGetKlass; +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES + gXmlSecSkeletonFunctions->keyDataDesGetKlass = xmlSecSkeletonKeyDataDesGetKlass; +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_DSA + gXmlSecSkeletonFunctions->keyDataDsaGetKlass = xmlSecSkeletonKeyDataDsaGetKlass; +#endif /* XMLSEC_NO_DSA */ + +#ifndef XMLSEC_NO_HMAC + gXmlSecSkeletonFunctions->keyDataHmacGetKlass = xmlSecSkeletonKeyDataHmacGetKlass; +#endif /* XMLSEC_NO_HMAC */ + +#ifndef XMLSEC_NO_RSA + gXmlSecSkeletonFunctions->keyDataRsaGetKlass = xmlSecSkeletonKeyDataRsaGetKlass; +#endif /* XMLSEC_NO_RSA */ + +#ifndef XMLSEC_NO_X509 + gXmlSecSkeletonFunctions->keyDataX509GetKlass = xmlSecSkeletonKeyDataX509GetKlass; + gXmlSecSkeletonFunctions->keyDataRawX509CertGetKlass = xmlSecSkeletonKeyDataRawX509CertGetKlass; +#endif /* XMLSEC_NO_X509 */ + + /** + * Key data store ids + */ +#ifndef XMLSEC_NO_X509 + gXmlSecSkeletonFunctions->x509StoreGetKlass = xmlSecSkeletonX509StoreGetKlass; +#endif /* XMLSEC_NO_X509 */ + + /** + * Crypto transforms ids + */ +#ifndef XMLSEC_NO_AES + gXmlSecSkeletonFunctions->transformAes128CbcGetKlass = xmlSecSkeletonTransformAes128CbcGetKlass; + gXmlSecSkeletonFunctions->transformAes192CbcGetKlass = xmlSecSkeletonTransformAes192CbcGetKlass; + gXmlSecSkeletonFunctions->transformAes256CbcGetKlass = xmlSecSkeletonTransformAes256CbcGetKlass; + gXmlSecSkeletonFunctions->transformKWAes128GetKlass = xmlSecSkeletonTransformKWAes128GetKlass; + gXmlSecSkeletonFunctions->transformKWAes192GetKlass = xmlSecSkeletonTransformKWAes192GetKlass; + gXmlSecSkeletonFunctions->transformKWAes256GetKlass = xmlSecSkeletonTransformKWAes256GetKlass; +#endif /* XMLSEC_NO_AES */ + +#ifndef XMLSEC_NO_DES + gXmlSecSkeletonFunctions->transformDes3CbcGetKlass = xmlSecSkeletonTransformDes3CbcGetKlass; + gXmlSecSkeletonFunctions->transformKWDes3GetKlass = xmlSecSkeletonTransformKWDes3GetKlass; +#endif /* XMLSEC_NO_DES */ + +#ifndef XMLSEC_NO_DSA + gXmlSecSkeletonFunctions->transformDsaSha1GetKlass = xmlSecSkeletonTransformDsaSha1GetKlass; +#endif /* XMLSEC_NO_DSA */ + +#ifndef XMLSEC_NO_HMAC + gXmlSecSkeletonFunctions->transformHmacSha1GetKlass = xmlSecSkeletonTransformHmacSha1GetKlass; + gXmlSecSkeletonFunctions->transformHmacRipemd160GetKlass = xmlSecSkeletonTransformHmacRipemd160GetKlass; + gXmlSecSkeletonFunctions->transformHmacMd5GetKlass = xmlSecSkeletonTransformHmacMd5GetKlass; +#endif /* XMLSEC_NO_HMAC */ + +#ifndef XMLSEC_NO_RIPEMD160 + gXmlSecSkeletonFunctions->transformRipemd160GetKlass = xmlSecSkeletonTransformRipemd160GetKlass; +#endif /* XMLSEC_NO_RIPEMD160 */ + +#ifndef XMLSEC_NO_RSA + gXmlSecSkeletonFunctions->transformRsaSha1GetKlass = xmlSecSkeletonTransformRsaSha1GetKlass; + gXmlSecSkeletonFunctions->transformRsaPkcs1GetKlass = xmlSecSkeletonTransformRsaPkcs1GetKlass; + gXmlSecSkeletonFunctions->transformRsaOaepGetKlass = xmlSecSkeletonTransformRsaOaepGetKlass; +#endif /* XMLSEC_NO_RSA */ + +#ifndef XMLSEC_NO_SHA1 + gXmlSecSkeletonFunctions->transformSha1GetKlass = xmlSecSkeletonTransformSha1GetKlass; +#endif /* XMLSEC_NO_SHA1 */ + + /** + * High level routines form xmlsec command line utility + */ + gXmlSecSkeletonFunctions->cryptoAppInit = xmlSecSkeletonAppInit; + gXmlSecSkeletonFunctions->cryptoAppShutdown = xmlSecSkeletonAppShutdown; + gXmlSecSkeletonFunctions->cryptoAppDefaultKeysMngrInit = xmlSecSkeletonAppDefaultKeysMngrInit; + gXmlSecSkeletonFunctions->cryptoAppDefaultKeysMngrAdoptKey = xmlSecSkeletonAppDefaultKeysMngrAdoptKey; + gXmlSecSkeletonFunctions->cryptoAppDefaultKeysMngrLoad = xmlSecSkeletonAppDefaultKeysMngrLoad; + gXmlSecSkeletonFunctions->cryptoAppDefaultKeysMngrSave = xmlSecSkeletonAppDefaultKeysMngrSave; +#ifndef XMLSEC_NO_X509 + gXmlSecSkeletonFunctions->cryptoAppKeysMngrCertLoad = xmlSecSkeletonAppKeysMngrCertLoad; + gXmlSecSkeletonFunctions->cryptoAppPkcs12Load = xmlSecSkeletonAppPkcs12Load; + gXmlSecSkeletonFunctions->cryptoAppKeyCertLoad = xmlSecSkeletonAppKeyCertLoad; +#endif /* XMLSEC_NO_X509 */ + gXmlSecSkeletonFunctions->cryptoAppKeyLoad = xmlSecSkeletonAppKeyLoad; + gXmlSecSkeletonFunctions->cryptoAppDefaultPwdCallback = (void*)xmlSecSkeletonAppGetDefaultPwdCallback; + + return(gXmlSecSkeletonFunctions); +} + /** * xmlSecSkeletonInit: @@ -32,23 +149,14 @@ static int xmlSecSkeletonTransformsInit (void); int xmlSecSkeletonInit (void) { /* TODO: if necessary do, additional initialization here */ - - if(xmlSecSkeletonKeysInit() < 0) { + if(xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms(xmlSecCryptoGetFunctions_skeleton()) < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, - "xmlSecSkeletonKeysInit", + "xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } - if(xmlSecSkeletonTransformsInit() < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecSkeletonTransformsInit", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(-1); - } return(0); } @@ -81,15 +189,4 @@ xmlSecSkeletonKeysMngrInit(xmlSecKeysMngrPtr mngr) { return(0); } -static int -xmlSecSkeletonKeysInit(void) { - /* TODO: register key data here */ - return(0); -} - -static int -xmlSecSkeletonTransformsInit(void) { - /* TODO: register transforms here */ - return(0); -} diff --git a/src/skeleton/globals.h b/src/skeleton/globals.h index 0f2bf445..272a27b8 100644 --- a/src/skeleton/globals.h +++ b/src/skeleton/globals.h @@ -11,8 +11,14 @@ #ifndef __XMLSEC_GLOBALS_H__ #define __XMLSEC_GLOBALS_H__ +/** + * Use autoconf defines if present. + */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif /* HAVE_CONFIG_H */ #define IN_XMLSEC_CRYPTO +#define XMLSEC_PRIVATE #endif /* ! __XMLSEC_GLOBALS_H__ */ diff --git a/src/xmlsec-ltdl.c b/src/xmlsec-ltdl.c new file mode 100644 index 00000000..183c8aa1 --- /dev/null +++ b/src/xmlsec-ltdl.c @@ -0,0 +1,3999 @@ +/* ltdl.c -- system independent dlopen wrapper + Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + Originally by Thomas Tanner <tanner@ffii.org> + This file is part of GNU Libtool. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU libtool, you may include it under the same +distribution terms that you use for the rest of that program. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA + +*/ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#if HAVE_UNISTD_H +# include <unistd.h> +#endif + +#if HAVE_STDIO_H +# include <stdio.h> +#endif + +#if HAVE_STDLIB_H +# include <stdlib.h> +#endif + +#if HAVE_STRING_H +# include <string.h> +#else +# if HAVE_STRINGS_H +# include <strings.h> +# endif +#endif + +#if HAVE_CTYPE_H +# include <ctype.h> +#endif + +#if HAVE_MALLOC_H +# include <malloc.h> +#endif + +#if HAVE_MEMORY_H +# include <memory.h> +#endif + +#if HAVE_ERRNO_H +# include <errno.h> +#endif + +#if HAVE_DIRENT_H +# include <dirent.h> +# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) +#else +# define dirent direct +# define LT_D_NAMLEN(dirent) ((dirent)->d_namlen) +# if HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif +# if HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif +# if HAVE_NDIR_H +# include <ndir.h> +# endif +#endif + +#if HAVE_ARGZ_H +# include <argz.h> +#endif + +#if HAVE_ASSERT_H +# include <assert.h> +#else +# define assert(arg) ((void) 0) +#endif + +#include "xmlsec-ltdl.h" + +#if WITH_DMALLOC +# include <dmalloc.h> +#endif + + + + +/* --- WINDOWS SUPPORT --- */ + + +#ifdef DLL_EXPORT +# define LT_GLOBAL_DATA __declspec(dllexport) +#else +# define LT_GLOBAL_DATA +#endif + +/* fopen() mode flags for reading a text file */ +#undef LT_READTEXT_MODE +#ifdef __WINDOWS__ +# define LT_READTEXT_MODE "rt" +#else +# define LT_READTEXT_MODE "r" +#endif + + + + +/* --- MANIFEST CONSTANTS --- */ + + +/* Standard libltdl search path environment variable name */ +#undef LTDL_SEARCHPATH_VAR +#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" + +/* Standard libtool archive file extension. */ +#undef LTDL_ARCHIVE_EXT +#define LTDL_ARCHIVE_EXT ".la" + +/* max. filename length */ +#ifndef LT_FILENAME_MAX +# define LT_FILENAME_MAX 1024 +#endif + +/* This is the maximum symbol size that won't require malloc/free */ +#undef LT_SYMBOL_LENGTH +#define LT_SYMBOL_LENGTH 128 + +/* This accounts for the _LTX_ separator */ +#undef LT_SYMBOL_OVERHEAD +#define LT_SYMBOL_OVERHEAD 5 + + + + +/* --- MEMORY HANDLING --- */ + + +/* These are the functions used internally. In addition to making + use of the associated function pointers above, they also perform + error handling. */ +static char *xmlsec_lt_estrdup LT_PARAMS((const char *str)); +static xmlsec_lt_ptr xmlsec_lt_emalloc LT_PARAMS((size_t size)); +static xmlsec_lt_ptr xmlsec_lt_erealloc LT_PARAMS((xmlsec_lt_ptr addr, size_t size)); + +static xmlsec_lt_ptr rpl_realloc LT_PARAMS((xmlsec_lt_ptr ptr, size_t size)); + +/* These are the pointers that can be changed by the caller: */ +LT_GLOBAL_DATA xmlsec_lt_ptr (*xmlsec_lt_dlmalloc) LT_PARAMS((size_t size)) + = (xmlsec_lt_ptr (*) LT_PARAMS((size_t))) malloc; +LT_GLOBAL_DATA xmlsec_lt_ptr (*xmlsec_lt_dlrealloc) LT_PARAMS((xmlsec_lt_ptr ptr, size_t size)) + = (xmlsec_lt_ptr (*) LT_PARAMS((xmlsec_lt_ptr, size_t))) rpl_realloc; +LT_GLOBAL_DATA void (*xmlsec_lt_dlfree) LT_PARAMS((xmlsec_lt_ptr ptr)) + = (void (*) LT_PARAMS((xmlsec_lt_ptr))) free; + +/* The following macros reduce the amount of typing needed to cast + assigned memory. */ +#if WITH_DMALLOC + +#define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) +#define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) +#define LT_DLFREE(p) \ + LT_STMT_START { if (p) (p) = (xfree (p), (xmlsec_lt_ptr) 0); } LT_STMT_END + +#define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) + +#else + +#define LT_DLMALLOC(tp, n) ((tp *) xmlsec_lt_dlmalloc ((n) * sizeof(tp))) +#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp))) +#define LT_DLFREE(p) \ + LT_STMT_START { if (p) (p) = (xmlsec_lt_dlfree (p), (xmlsec_lt_ptr) 0); } LT_STMT_END + +#define LT_EMALLOC(tp, n) ((tp *) xmlsec_lt_emalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) xmlsec_lt_erealloc ((p), (n) * sizeof(tp))) + +#endif + +#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \ + if ((p) != (q)) { if (p) xmlsec_lt_dlfree (p); (p) = (q); (q) = 0; } \ + } LT_STMT_END + + +/* --- REPLACEMENT FUNCTIONS --- */ + + +#undef strdup +#define strdup rpl_strdup + +static char *strdup LT_PARAMS((const char *str)); + +static char * +strdup(str) + const char *str; +{ + char *tmp = NULL; + + if (str) + { + tmp = LT_DLMALLOC (char, 1+ strlen (str)); + if (tmp) + { + strcpy(tmp, str); + } + } + + return tmp; +} + + +#if ! HAVE_STRCMP + +#undef strcmp +#define strcmp rpl_strcmp + +static int strcmp LT_PARAMS((const char *str1, const char *str2)); + +static int +strcmp (str1, str2) + const char *str1; + const char *str2; +{ + if (str1 == str2) + return 0; + if (str1 == NULL) + return -1; + if (str2 == NULL) + return 1; + + for (;*str1 && *str2; ++str1, ++str2) + { + if (*str1 != *str2) + break; + } + + return (int)(*str1 - *str2); +} +#endif + + +#if ! HAVE_STRCHR + +# if HAVE_INDEX +# define strchr index +# else +# define strchr rpl_strchr + +static const char *strchr LT_PARAMS((const char *str, int ch)); + +static const char* +strchr(str, ch) + const char *str; + int ch; +{ + const char *p; + + for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p) + /*NOWORK*/; + + return (*p == (char)ch) ? p : 0; +} + +# endif +#endif /* !HAVE_STRCHR */ + + +#if ! HAVE_STRRCHR + +# if HAVE_RINDEX +# define strrchr rindex +# else +# define strrchr rpl_strrchr + +static const char *strrchr LT_PARAMS((const char *str, int ch)); + +static const char* +strrchr(str, ch) + const char *str; + int ch; +{ + const char *p, *q = NULL; + + for (p = str; *p != LT_EOS_CHAR; ++p) + { + if (*p == (char) ch) + { + q = p; + } + } + + return q; +} + +# endif +#endif + +/* NOTE: Neither bcopy nor the memcpy implementation below can + reliably handle copying in overlapping areas of memory. Use + memmove (for which there is a fallback implmentation below) + if you need that behaviour. */ +#if ! HAVE_MEMCPY + +# if HAVE_BCOPY +# define memcpy(dest, src, size) bcopy (src, dest, size) +# else +# define memcpy rpl_memcpy + +static xmlsec_lt_ptr memcpy LT_PARAMS((xmlsec_lt_ptr dest, const xmlsec_lt_ptr src, size_t size)); + +static xmlsec_lt_ptr +memcpy (dest, src, size) + xmlsec_lt_ptr dest; + const xmlsec_lt_ptr src; + size_t size; +{ + size_t i = 0; + + for (i = 0; i < size; ++i) + { + dest[i] = src[i]; + } + + return dest; +} + +# endif /* !HAVE_BCOPY */ +#endif /* !HAVE_MEMCPY */ + +#if ! HAVE_MEMMOVE +# define memmove rpl_memmove + +static xmlsec_lt_ptr memmove LT_PARAMS((xmlsec_lt_ptr dest, const xmlsec_lt_ptr src, size_t size)); + +static xmlsec_lt_ptr +memmove (dest, src, size) + xmlsec_lt_ptr dest; + const xmlsec_lt_ptr src; + size_t size; +{ + size_t i; + + if (dest < src) + for (i = 0; i < size; ++i) + { + dest[i] = src[i]; + } + else if (dest > src) + for (i = size -1; i >= 0; --i) + { + dest[i] = src[i]; + } + + return dest; +} + +#endif /* !HAVE_MEMMOVE */ + + +/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>, + ``realloc is not entirely portable'' + In any case we want to use the allocator supplied by the user without + burdening them with an xmlsec_lt_dlrealloc function pointer to maintain. + Instead implement our own version (with known boundary conditions) + using xmlsec_lt_dlmalloc and xmlsec_lt_dlfree. */ + +#undef realloc +#define realloc rpl_realloc + +static xmlsec_lt_ptr +realloc (ptr, size) + xmlsec_lt_ptr ptr; + size_t size; +{ + if (size == 0) + { + /* For zero or less bytes, free the original memory */ + if (ptr != NULL) + { + xmlsec_lt_dlfree (ptr); + } + + return (xmlsec_lt_ptr) 0; + } + else if (ptr == NULL) + { + /* Allow reallocation of a NULL pointer. */ + return xmlsec_lt_dlmalloc (size); + } + else + { + /* Allocate a new block, copy and free the old block. */ + xmlsec_lt_ptr mem = xmlsec_lt_dlmalloc (size); + + if (mem) + { + memcpy (mem, ptr, size); + xmlsec_lt_dlfree (ptr); + } + + /* Note that the contents of PTR are not damaged if there is + insufficient memory to realloc. */ + return mem; + } +} + + +#if ! HAVE_ARGZ_APPEND +# define argz_append rpl_argz_append + +static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len, + const char *buf, size_t buf_len)); + +static error_t +argz_append (pargz, pargz_len, buf, buf_len) + char **pargz; + size_t *pargz_len; + const char *buf; + size_t buf_len; +{ + size_t argz_len; + char *argz; + + assert (pargz); + assert (pargz_len); + assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); + + /* If nothing needs to be appended, no more work is required. */ + if (buf_len == 0) + return 0; + + /* Ensure there is enough room to append BUF_LEN. */ + argz_len = *pargz_len + buf_len; + argz = LT_DLREALLOC (char, *pargz, argz_len); + if (!argz) + return ENOMEM; + + /* Copy characters from BUF after terminating '\0' in ARGZ. */ + memcpy (argz + *pargz_len, buf, buf_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} +#endif /* !HAVE_ARGZ_APPEND */ + + +#if ! HAVE_ARGZ_CREATE_SEP +# define argz_create_sep rpl_argz_create_sep + +static error_t argz_create_sep LT_PARAMS((const char *str, int delim, + char **pargz, size_t *pargz_len)); + +static error_t +argz_create_sep (str, delim, pargz, pargz_len) + const char *str; + int delim; + char **pargz; + size_t *pargz_len; +{ + size_t argz_len; + char *argz = NULL; + + assert (str); + assert (pargz); + assert (pargz_len); + + /* Make a copy of STR, but replacing each occurence of + DELIM with '\0'. */ + argz_len = 1+ LT_STRLEN (str); + if (argz_len) + { + const char *p; + char *q; + + argz = LT_DLMALLOC (char, argz_len); + if (!argz) + return ENOMEM; + + for (p = str, q = argz; *p != LT_EOS_CHAR; ++p) + { + if (*p == delim) + { + /* Ignore leading delimiters, and fold consecutive + delimiters in STR into a single '\0' in ARGZ. */ + if ((q > argz) && (q[-1] != LT_EOS_CHAR)) + *q++ = LT_EOS_CHAR; + else + --argz_len; + } + else + *q++ = *p; + } + /* Copy terminating LT_EOS_CHAR. */ + *q = *p; + } + + /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ + if (!argz_len) + LT_DLFREE (argz); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} +#endif /* !HAVE_ARGZ_CREATE_SEP */ + + +#if ! HAVE_ARGZ_INSERT +# define argz_insert rpl_argz_insert + +static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len, + char *before, const char *entry)); + +static error_t +argz_insert (pargz, pargz_len, before, entry) + char **pargz; + size_t *pargz_len; + char *before; + const char *entry; +{ + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + /* No BEFORE address indicates ENTRY should be inserted after the + current last element. */ + if (!before) + return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry)); + + /* This probably indicates a programmer error, but to preserve + semantics, scan back to the start of an entry if BEFORE points + into the middle of it. */ + while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR)) + --before; + + { + size_t entry_len = 1+ LT_STRLEN (entry); + size_t argz_len = *pargz_len + entry_len; + size_t offset = before - *pargz; + char *argz = LT_DLREALLOC (char, *pargz, argz_len); + + if (!argz) + return ENOMEM; + + /* Make BEFORE point to the equivalent offset in ARGZ that it + used to have in *PARGZ incase realloc() moved the block. */ + before = argz + offset; + + /* Move the ARGZ entries starting at BEFORE up into the new + space at the end -- making room to copy ENTRY into the + resulting gap. */ + memmove (before + entry_len, before, *pargz_len - offset); + memcpy (before, entry, entry_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + } + + return 0; +} +#endif /* !HAVE_ARGZ_INSERT */ + + +#if ! HAVE_ARGZ_NEXT +# define argz_next rpl_argz_next + +static char *argz_next LT_PARAMS((char *argz, size_t argz_len, + const char *entry)); + +static char * +argz_next (argz, argz_len, entry) + char *argz; + size_t argz_len; + const char *entry; +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (entry) + { + /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address + within the ARGZ vector. */ + assert ((!argz && !argz_len) + || ((argz <= entry) && (entry < (argz + argz_len)))); + + /* Move to the char immediately after the terminating + '\0' of ENTRY. */ + entry = 1+ strchr (entry, LT_EOS_CHAR); + + /* Return either the new ENTRY, or else NULL if ARGZ is + exhausted. */ + return (entry >= argz + argz_len) ? 0 : (char *) entry; + } + else + { + /* This should probably be flagged as a programmer error, + since starting an argz_next loop with the iterator set + to ARGZ is safer. To preserve semantics, handle the NULL + case by returning the start of ARGZ (if any). */ + if (argz_len > 0) + return argz; + else + return 0; + } +} +#endif /* !HAVE_ARGZ_NEXT */ + + + +#if ! HAVE_ARGZ_STRINGIFY +# define argz_stringify rpl_argz_stringify + +static void argz_stringify LT_PARAMS((char *argz, size_t argz_len, + int sep)); + +static void +argz_stringify (argz, argz_len, sep) + char *argz; + size_t argz_len; + int sep; +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (sep) + { + --argz_len; /* don't stringify the terminating EOS */ + while (--argz_len > 0) + { + if (argz[argz_len] == LT_EOS_CHAR) + argz[argz_len] = sep; + } + } +} +#endif /* !HAVE_ARGZ_STRINGIFY */ + + + + +/* --- TYPE DEFINITIONS -- */ + + +/* This type is used for the array of caller data sets in each handler. */ +typedef struct { + xmlsec_lt_dlcaller_id key; + xmlsec_lt_ptr data; +} xmlsec_lt_caller_data; + + + + +/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */ + + +/* Extract the diagnostic strings from the error table macro in the same + order as the enumerated indices in xmlsec-ltdl.h. */ + +static const char *xmlsec_lt_dlerror_strings[] = + { +#define LT_ERROR(name, diagnostic) (diagnostic), + xmlsec_lt_dlerror_table +#undef LT_ERROR + + 0 + }; + +/* This structure is used for the list of registered loaders. */ +struct xmlsec_lt_dlloader { + struct xmlsec_lt_dlloader *next; + const char *loader_name; /* identifying name for each loader */ + const char *sym_prefix; /* prefix for symbols */ + xmlsec_lt_module_open *module_open; + xmlsec_lt_module_close *module_close; + xmlsec_lt_find_sym *find_sym; + xmlsec_lt_dlloader_exit *dlloader_exit; + xmlsec_lt_user_data dlloader_data; +}; + +struct xmlsec_lt_dlhandle_struct { + struct xmlsec_lt_dlhandle_struct *next; + xmlsec_lt_dlloader *loader; /* dlopening interface */ + xmlsec_lt_dlinfo info; + int depcount; /* number of dependencies */ + xmlsec_lt_dlhandle *deplibs; /* dependencies */ + xmlsec_lt_module module; /* system module handle */ + xmlsec_lt_ptr system; /* system specific data */ + xmlsec_lt_caller_data *caller_data; /* per caller associated data */ + int flags; /* various boolean stats */ +}; + +/* Various boolean flags can be stored in the flags field of an + xmlsec_lt_dlhandle_struct... */ +#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag)) +#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag)) + +#define LT_DLRESIDENT_FLAG (0x01 << 0) +/* ...add more flags here... */ + +#define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG) + + +#define LT_DLSTRERROR(name) xmlsec_lt_dlerror_strings[LT_CONC(LT_ERROR_,name)] + +static const char objdir[] = LTDL_OBJDIR; +static const char archive_ext[] = LTDL_ARCHIVE_EXT; +#ifdef LTDL_SHLIB_EXT +static const char shlib_ext[] = LTDL_SHLIB_EXT; +#endif +#ifdef LTDL_SYSSEARCHPATH +static const char sys_search_path[] = LTDL_SYSSEARCHPATH; +#endif + + + + +/* --- MUTEX LOCKING --- */ + + +/* Macros to make it easier to run the lock functions only if they have + been registered. The reason for the complicated lock macro is to + ensure that the stored error message from the last error is not + accidentally erased if the current function doesn't generate an + error of its own. */ +#define LT_DLMUTEX_LOCK() LT_STMT_START { \ + if (xmlsec_lt_dlmutex_lock_func) (*xmlsec_lt_dlmutex_lock_func)(); \ + } LT_STMT_END +#define LT_DLMUTEX_UNLOCK() LT_STMT_START { \ + if (xmlsec_lt_dlmutex_unlock_func) (*xmlsec_lt_dlmutex_unlock_func)();\ + } LT_STMT_END +#define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \ + if (xmlsec_lt_dlmutex_seterror_func) \ + (*xmlsec_lt_dlmutex_seterror_func) (errormsg); \ + else xmlsec_lt_dllast_error = (errormsg); } LT_STMT_END +#define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \ + if (xmlsec_lt_dlmutex_seterror_func) \ + (errormsg) = (*xmlsec_lt_dlmutex_geterror_func) (); \ + else (errormsg) = xmlsec_lt_dllast_error; } LT_STMT_END + +/* The mutex functions stored here are global, and are necessarily the + same for all threads that wish to share access to libltdl. */ +static xmlsec_lt_dlmutex_lock *xmlsec_lt_dlmutex_lock_func = NULL; +static xmlsec_lt_dlmutex_unlock *xmlsec_lt_dlmutex_unlock_func = NULL; +static xmlsec_lt_dlmutex_seterror *xmlsec_lt_dlmutex_seterror_func = NULL; +static xmlsec_lt_dlmutex_geterror *xmlsec_lt_dlmutex_geterror_func = NULL; +static const char *xmlsec_lt_dllast_error = NULL; + + +/* Either set or reset the mutex functions. Either all the arguments must + be valid functions, or else all can be NULL to turn off locking entirely. + The registered functions should be manipulating a static global lock + from the lock() and unlock() callbacks, which needs to be reentrant. */ +int +xmlsec_lt_dlmutex_register (lock, unlock, seterror, geterror) + xmlsec_lt_dlmutex_lock *lock; + xmlsec_lt_dlmutex_unlock *unlock; + xmlsec_lt_dlmutex_seterror *seterror; + xmlsec_lt_dlmutex_geterror *geterror; +{ + xmlsec_lt_dlmutex_unlock *old_unlock = unlock; + int errors = 0; + + /* Lock using the old lock() callback, if any. */ + LT_DLMUTEX_LOCK (); + + if ((lock && unlock && seterror && geterror) + || !(lock || unlock || seterror || geterror)) + { + xmlsec_lt_dlmutex_lock_func = lock; + xmlsec_lt_dlmutex_unlock_func = unlock; + xmlsec_lt_dlmutex_geterror_func = geterror; + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS)); + ++errors; + } + + /* Use the old unlock() callback we saved earlier, if any. Otherwise + record any errors using internal storage. */ + if (old_unlock) + (*old_unlock) (); + + /* Return the number of errors encountered during the execution of + this function. */ + return errors; +} + + + + +/* --- ERROR HANDLING --- */ + + +static const char **user_error_strings = NULL; +static int errorcount = LT_ERROR_MAX; + +int +xmlsec_lt_dladderror (diagnostic) + const char *diagnostic; +{ + int errindex = 0; + int result = -1; + const char **temp = NULL; + + assert (diagnostic); + + LT_DLMUTEX_LOCK (); + + errindex = errorcount - LT_ERROR_MAX; + temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex); + if (temp) + { + user_error_strings = temp; + user_error_strings[errindex] = diagnostic; + result = errorcount++; + } + + LT_DLMUTEX_UNLOCK (); + + return result; +} + +int +xmlsec_lt_dlseterror (errindex) + int errindex; +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + if (errindex >= errorcount || errindex < 0) + { + /* Ack! Error setting the error message! */ + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE)); + ++errors; + } + else if (errindex < LT_ERROR_MAX) + { + /* No error setting the error message! */ + LT_DLMUTEX_SETERROR (xmlsec_lt_dlerror_strings[errindex]); + } + else + { + /* No error setting the error message! */ + LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]); + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static xmlsec_lt_ptr +xmlsec_lt_emalloc (size) + size_t size; +{ + xmlsec_lt_ptr mem = xmlsec_lt_dlmalloc (size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; +} + +static xmlsec_lt_ptr +xmlsec_lt_erealloc (addr, size) + xmlsec_lt_ptr addr; + size_t size; +{ + xmlsec_lt_ptr mem = realloc (addr, size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; +} + +static char * +xmlsec_lt_estrdup (str) + const char *str; +{ + char *copy = strdup (str); + if (LT_STRLEN (str) && !copy) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return copy; +} + + + + +/* --- DLOPEN() INTERFACE LOADER --- */ + + +/* The Cygwin dlopen implementation prints a spurious error message to + stderr if its call to LoadLibrary() fails for any reason. We can + mitigate this by not using the Cygwin implementation, and falling + back to our own LoadLibrary() wrapper. */ +#if HAVE_LIBDL && !defined(__CYGWIN__) + +/* dynamic linking with dlopen/dlsym */ + +#if HAVE_DLFCN_H +# include <dlfcn.h> +#endif + +#if HAVE_SYS_DL_H +# include <sys/dl.h> +#endif + +#ifdef RTLD_GLOBAL +# define LT_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_GLOBAL DL_GLOBAL +# endif +#endif /* !RTLD_GLOBAL */ +#ifndef LT_GLOBAL +# define LT_GLOBAL 0 +#endif /* !LT_GLOBAL */ + +/* We may have to define LT_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_LAZY_OR_NOW DL_LAZY +# endif +# endif /* !RTLD_LAZY */ +#endif +#ifndef LT_LAZY_OR_NOW +# ifdef RTLD_NOW +# define LT_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_LAZY_OR_NOW DL_NOW +# endif +# endif /* !RTLD_NOW */ +#endif +#ifndef LT_LAZY_OR_NOW +# define LT_LAZY_OR_NOW 0 +#endif /* !LT_LAZY_OR_NOW */ + +#if HAVE_DLERROR +# define DLERROR(arg) dlerror () +#else +# define DLERROR(arg) LT_DLSTRERROR (arg) +#endif + +static xmlsec_lt_module +sys_dl_open (loader_data, filename) + xmlsec_lt_user_data loader_data; + const char *filename; +{ + xmlsec_lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW); + + if (!module) + { + LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN)); + } + + return module; +} + +static int +sys_dl_close (loader_data, module) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; +{ + int errors = 0; + + if (dlclose (module) != 0) + { + LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static xmlsec_lt_ptr +sys_dl_sym (loader_data, module, symbol) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; + const char *symbol; +{ + xmlsec_lt_ptr address = dlsym (module, symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct xmlsec_lt_user_dlloader sys_dl = + { +# ifdef NEED_USCORE + "_", +# else + 0, +# endif + sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 }; + + +#endif /* HAVE_LIBDL */ + + + +/* --- SHL_LOAD() INTERFACE LOADER --- */ + +#if HAVE_SHL_LOAD + +/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */ + +#ifdef HAVE_DL_H +# include <dl.h> +#endif + +/* some flags are missing on some systems, so we provide + * harmless defaults. + * + * Mandatory: + * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. + * BIND_DEFERRED - Delay code symbol resolution until actual reference. + * + * Optionally: + * BIND_FIRST - Place the library at the head of the symbol search + * order. + * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all + * unsatisfied symbols as fatal. This flag allows + * binding of unsatisfied code symbols to be deferred + * until use. + * [Perl: For certain libraries, like DCE, deferred + * binding often causes run time problems. Adding + * BIND_NONFATAL to BIND_IMMEDIATE still allows + * unresolved references in situations like this.] + * BIND_NOSTART - Do not call the initializer for the shared library + * when the library is loaded, nor on a future call to + * shl_unload(). + * BIND_VERBOSE - Print verbose messages concerning possible + * unsatisfied symbols. + * + * hp9000s700/hp9000s800: + * BIND_RESTRICTED - Restrict symbols visible by the library to those + * present at library load time. + * DYNAMIC_PATH - Allow the loader to dynamically search for the + * library specified by the path argument. + */ + +#ifndef DYNAMIC_PATH +# define DYNAMIC_PATH 0 +#endif +#ifndef BIND_RESTRICTED +# define BIND_RESTRICTED 0 +#endif + +#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH) + +static xmlsec_lt_module +sys_shl_open (loader_data, filename) + xmlsec_lt_user_data loader_data; + const char *filename; +{ + static shl_t self = (shl_t) 0; + xmlsec_lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); + + /* Since searching for a symbol against a NULL module handle will also + look in everything else that was already loaded and exported with + the -E compiler flag, we always cache a handle saved before any + modules are loaded. */ + if (!self) + { + xmlsec_lt_ptr address; + shl_findsym (&self, "main", TYPE_UNDEFINED, &address); + } + + if (!filename) + { + module = self; + } + else + { + module = shl_load (filename, LT_BIND_FLAGS, 0L); + + if (!module) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + } + } + + return module; +} + +static int +sys_shl_close (loader_data, module) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; +{ + int errors = 0; + + if (module && (shl_unload ((shl_t) (module)) != 0)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static xmlsec_lt_ptr +sys_shl_sym (loader_data, module, symbol) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; + const char *symbol; +{ + xmlsec_lt_ptr address = NULL; + + /* sys_shl_open should never return a NULL module handle */ + if (module == (xmlsec_lt_module) 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + } + else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address)) + { + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + } + + return address; +} + +static struct xmlsec_lt_user_dlloader sys_shl = { + 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0 +}; + +#endif /* HAVE_SHL_LOAD */ + + + + +/* --- LOADLIBRARY() INTERFACE LOADER --- */ + +#ifdef __WINDOWS__ + +/* dynamic linking for Win32 */ + +#include <windows.h> + +/* Forward declaration; required to implement handle search below. */ +static xmlsec_lt_dlhandle handles; + +static xmlsec_lt_module +sys_wll_open (loader_data, filename) + xmlsec_lt_user_data loader_data; + const char *filename; +{ + xmlsec_lt_dlhandle cur; + xmlsec_lt_module module = NULL; + const char *errormsg = NULL; + char *searchname = NULL; + char *ext; + char self_name_buf[MAX_PATH]; + + if (!filename) + { + /* Get the name of main module */ + *self_name_buf = '\0'; + GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf)); + filename = ext = self_name_buf; + } + else + { + ext = strrchr (filename, '.'); + } + + if (ext) + { + /* FILENAME already has an extension. */ + searchname = xmlsec_lt_estrdup (filename); + } + else + { + /* Append a `.' to stop Windows from adding an + implicit `.dll' extension. */ + searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename)); + if (searchname) + sprintf (searchname, "%s.", filename); + } + if (!searchname) + return 0; + +#if __CYGWIN__ + { + char wpath[MAX_PATH]; + cygwin_conv_to_full_win32_path(searchname, wpath); + module = LoadLibrary(wpath); + } +#else + module = LoadLibrary (searchname); +#endif + LT_DLFREE (searchname); + + /* libltdl expects this function to fail if it is unable + to physically load the library. Sadly, LoadLibrary + will search the loaded libraries for a match and return + one of them if the path search load fails. + + We check whether LoadLibrary is returning a handle to + an already loaded module, and simulate failure if we + find one. */ + LT_DLMUTEX_LOCK (); + cur = handles; + while (cur) + { + if (!cur->module) + { + cur = NULL; + break; + } + + if (cur->module == module) + { + break; + } + + cur = cur->next; + } + LT_DLMUTEX_UNLOCK (); + + if (cur || !module) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + module = NULL; + } + + return module; +} + +static int +sys_wll_close (loader_data, module) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; +{ + int errors = 0; + + if (FreeLibrary(module) == 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static xmlsec_lt_ptr +sys_wll_sym (loader_data, module, symbol) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; + const char *symbol; +{ + xmlsec_lt_ptr address = GetProcAddress (module, symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct xmlsec_lt_user_dlloader sys_wll = { + 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0 +}; + +#endif /* __WINDOWS__ */ + + + + +/* --- LOAD_ADD_ON() INTERFACE LOADER --- */ + + +#ifdef __BEOS__ + +/* dynamic linking for BeOS */ + +#include <kernel/image.h> + +static xmlsec_lt_module +sys_bedl_open (loader_data, filename) + xmlsec_lt_user_data loader_data; + const char *filename; +{ + image_id image = 0; + + if (filename) + { + image = load_add_on (filename); + } + else + { + image_info info; + int32 cookie = 0; + if (get_next_image_info (0, &cookie, &info) == B_OK) + image = load_add_on (info.name); + } + + if (image <= 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + image = 0; + } + + return (xmlsec_lt_module) image; +} + +static int +sys_bedl_close (loader_data, module) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; +{ + int errors = 0; + + if (unload_add_on ((image_id) module) != B_OK) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static xmlsec_lt_ptr +sys_bedl_sym (loader_data, module, symbol) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; + const char *symbol; +{ + xmlsec_lt_ptr address = NULL; + image_id image = (image_id) module; + + if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + address = NULL; + } + + return address; +} + +static struct xmlsec_lt_user_dlloader sys_bedl = { + 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0 +}; + +#endif /* __BEOS__ */ + + + + +/* --- DLD_LINK() INTERFACE LOADER --- */ + + +#if HAVE_DLD + +/* dynamic linking with dld */ + +#if HAVE_DLD_H +#include <dld.h> +#endif + +static xmlsec_lt_module +sys_dld_open (loader_data, filename) + xmlsec_lt_user_data loader_data; + const char *filename; +{ + xmlsec_lt_module module = strdup (filename); + + if (dld_link (filename) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + LT_DLFREE (module); + module = NULL; + } + + return module; +} + +static int +sys_dld_close (loader_data, module) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; +{ + int errors = 0; + + if (dld_unlink_by_file ((char*)(module), 1) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + else + { + LT_DLFREE (module); + } + + return errors; +} + +static xmlsec_lt_ptr +sys_dld_sym (loader_data, module, symbol) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; + const char *symbol; +{ + xmlsec_lt_ptr address = dld_get_func (symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct xmlsec_lt_user_dlloader sys_dld = { + 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 +}; + +#endif /* HAVE_DLD */ + + + + +/* --- DLPREOPEN() INTERFACE LOADER --- */ + + +/* emulate dynamic linking using preloaded_symbols */ + +typedef struct xmlsec_lt_dlsymlists_t +{ + struct xmlsec_lt_dlsymlists_t *next; + const xmlsec_lt_dlsymlist *syms; +} xmlsec_lt_dlsymlists_t; + +static const xmlsec_lt_dlsymlist *defauxmlsec_lt_preloaded_symbols = NULL; +static xmlsec_lt_dlsymlists_t *preloaded_symbols = NULL; + +static int +presym_init (loader_data) + xmlsec_lt_user_data loader_data; +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + preloaded_symbols = NULL; + if (defauxmlsec_lt_preloaded_symbols) + { + errors = xmlsec_lt_dlpreload (defauxmlsec_lt_preloaded_symbols); + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static int +presym_free_symlists () +{ + xmlsec_lt_dlsymlists_t *lists; + + LT_DLMUTEX_LOCK (); + + lists = preloaded_symbols; + while (lists) + { + xmlsec_lt_dlsymlists_t *tmp = lists; + + lists = lists->next; + LT_DLFREE (tmp); + } + preloaded_symbols = NULL; + + LT_DLMUTEX_UNLOCK (); + + return 0; +} + +static int +presym_exit (loader_data) + xmlsec_lt_user_data loader_data; +{ + presym_free_symlists (); + return 0; +} + +static int +presym_add_symlist (preloaded) + const xmlsec_lt_dlsymlist *preloaded; +{ + xmlsec_lt_dlsymlists_t *tmp; + xmlsec_lt_dlsymlists_t *lists; + int errors = 0; + + LT_DLMUTEX_LOCK (); + + lists = preloaded_symbols; + while (lists) + { + if (lists->syms == preloaded) + { + goto done; + } + lists = lists->next; + } + + tmp = LT_EMALLOC (xmlsec_lt_dlsymlists_t, 1); + if (tmp) + { + memset (tmp, 0, sizeof(xmlsec_lt_dlsymlists_t)); + tmp->syms = preloaded; + tmp->next = preloaded_symbols; + preloaded_symbols = tmp; + } + else + { + ++errors; + } + + done: + LT_DLMUTEX_UNLOCK (); + return errors; +} + +static xmlsec_lt_module +presym_open (loader_data, filename) + xmlsec_lt_user_data loader_data; + const char *filename; +{ + xmlsec_lt_dlsymlists_t *lists; + xmlsec_lt_module module = (xmlsec_lt_module) 0; + + LT_DLMUTEX_LOCK (); + lists = preloaded_symbols; + + if (!lists) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS)); + goto done; + } + + /* Can't use NULL as the reflective symbol header, as NULL is + used to mark the end of the entire symbol list. Self-dlpreopened + symbols follow this magic number, chosen to be an unlikely + clash with a real module name. */ + if (!filename) + { + filename = "@PROGRAM@"; + } + + while (lists) + { + const xmlsec_lt_dlsymlist *syms = lists->syms; + + while (syms->name) + { + if (!syms->address && strcmp(syms->name, filename) == 0) + { + module = (xmlsec_lt_module) syms; + goto done; + } + ++syms; + } + + lists = lists->next; + } + + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + + done: + LT_DLMUTEX_UNLOCK (); + return module; +} + +static int +presym_close (loader_data, module) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; +{ + /* Just to silence gcc -Wall */ + module = NULL; + return 0; +} + +static xmlsec_lt_ptr +presym_sym (loader_data, module, symbol) + xmlsec_lt_user_data loader_data; + xmlsec_lt_module module; + const char *symbol; +{ + xmlsec_lt_dlsymlist *syms = (xmlsec_lt_dlsymlist*) module; + + ++syms; + while (syms->address) + { + if (strcmp(syms->name, symbol) == 0) + { + return syms->address; + } + + ++syms; + } + + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + + return 0; +} + +static struct xmlsec_lt_user_dlloader presym = { + 0, presym_open, presym_close, presym_sym, presym_exit, 0 +}; + + + + + +/* --- DYNAMIC MODULE LOADING --- */ + + +/* The type of a function used at each iteration of foreach_dirinpath(). */ +typedef int foreach_callback_func LT_PARAMS((char *filename, xmlsec_lt_ptr data1, + xmlsec_lt_ptr data2)); + +static int foreach_dirinpath LT_PARAMS((const char *search_path, + const char *base_name, + foreach_callback_func *func, + xmlsec_lt_ptr data1, xmlsec_lt_ptr data2)); + +static int find_file_callback LT_PARAMS((char *filename, xmlsec_lt_ptr data, + xmlsec_lt_ptr ignored)); +static int find_handle_callback LT_PARAMS((char *filename, xmlsec_lt_ptr data, + xmlsec_lt_ptr ignored)); +static int foreachfile_callback LT_PARAMS((char *filename, xmlsec_lt_ptr data1, + xmlsec_lt_ptr data2)); + + +static int canonicalize_path LT_PARAMS((const char *path, + char **pcanonical)); +static int argzize_path LT_PARAMS((const char *path, + char **pargz, + size_t *pargz_len)); +static FILE *find_file LT_PARAMS((const char *search_path, + const char *base_name, + char **pdir)); +static xmlsec_lt_dlhandle *find_handle LT_PARAMS((const char *search_path, + const char *base_name, + xmlsec_lt_dlhandle *handle)); +static int find_module LT_PARAMS((xmlsec_lt_dlhandle *handle, + const char *dir, + const char *libdir, + const char *dlname, + const char *old_name, + int installed)); +static int free_vars LT_PARAMS((char *dlname, char *oldname, + char *libdir, char *deplibs)); +static int load_deplibs LT_PARAMS((xmlsec_lt_dlhandle handle, + char *deplibs)); +static int trim LT_PARAMS((char **dest, + const char *str)); +static int try_dlopen LT_PARAMS((xmlsec_lt_dlhandle *handle, + const char *filename)); +static int tryall_dlopen LT_PARAMS((xmlsec_lt_dlhandle *handle, + const char *filename)); +static int unload_deplibs LT_PARAMS((xmlsec_lt_dlhandle handle)); +static int xmlsec_lt_argz_insert LT_PARAMS((char **pargz, + size_t *pargz_len, + char *before, + const char *entry)); +static int xmlsec_lt_argz_insertinorder LT_PARAMS((char **pargz, + size_t *pargz_len, + const char *entry)); +static int xmlsec_lt_argz_insertdir LT_PARAMS((char **pargz, + size_t *pargz_len, + const char *dirnam, + struct dirent *dp)); +static int xmlsec_lt_dlpath_insertdir LT_PARAMS((char **ppath, + char *before, + const char *dir)); +static int list_files_by_dir LT_PARAMS((const char *dirnam, + char **pargz, + size_t *pargz_len)); +static int file_not_found LT_PARAMS((void)); + +static char *user_search_path= NULL; +static xmlsec_lt_dlloader *loaders = NULL; +static xmlsec_lt_dlhandle handles = NULL; +static int initialized = 0; + +/* Initialize libltdl. */ +int +xmlsec_lt_dlinit () +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + /* Initialize only at first call. */ + if (++initialized == 1) + { + handles = NULL; + user_search_path = NULL; /* empty search path */ + +#if HAVE_LIBDL && !defined(__CYGWIN__) + errors += xmlsec_lt_dlloader_add (xmlsec_lt_dlloader_next (0), &sys_dl, "dlopen"); +#endif +#if HAVE_SHL_LOAD + errors += xmlsec_lt_dlloader_add (xmlsec_lt_dlloader_next (0), &sys_shl, "dlopen"); +#endif +#ifdef __WINDOWS__ + errors += xmlsec_lt_dlloader_add (xmlsec_lt_dlloader_next (0), &sys_wll, "dlopen"); +#endif +#ifdef __BEOS__ + errors += xmlsec_lt_dlloader_add (xmlsec_lt_dlloader_next (0), &sys_bedl, "dlopen"); +#endif +#if HAVE_DLD + errors += xmlsec_lt_dlloader_add (xmlsec_lt_dlloader_next (0), &sys_dld, "dld"); +#endif + errors += xmlsec_lt_dlloader_add (xmlsec_lt_dlloader_next (0), &presym, "dlpreload"); + + if (presym_init (presym.dlloader_data)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER)); + ++errors; + } + else if (errors != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED)); + ++errors; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +int +xmlsec_lt_dlpreload (preloaded) + const xmlsec_lt_dlsymlist *preloaded; +{ + int errors = 0; + + if (preloaded) + { + errors = presym_add_symlist (preloaded); + } + else + { + presym_free_symlists(); + + LT_DLMUTEX_LOCK (); + if (defauxmlsec_lt_preloaded_symbols) + { + errors = xmlsec_lt_dlpreload (defauxmlsec_lt_preloaded_symbols); + } + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +xmlsec_lt_dlpreload_default (preloaded) + const xmlsec_lt_dlsymlist *preloaded; +{ + LT_DLMUTEX_LOCK (); + defauxmlsec_lt_preloaded_symbols = preloaded; + LT_DLMUTEX_UNLOCK (); + return 0; +} + +int +xmlsec_lt_dlexit () +{ + /* shut down libltdl */ + xmlsec_lt_dlloader *loader; + int errors = 0; + + LT_DLMUTEX_LOCK (); + loader = loaders; + + if (!initialized) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN)); + ++errors; + goto done; + } + + /* shut down only at last call. */ + if (--initialized == 0) + { + int level; + + while (handles && LT_DLIS_RESIDENT (handles)) + { + handles = handles->next; + } + + /* close all modules */ + for (level = 1; handles; ++level) + { + xmlsec_lt_dlhandle cur = handles; + int saw_nonresident = 0; + + while (cur) + { + xmlsec_lt_dlhandle tmp = cur; + cur = cur->next; + if (!LT_DLIS_RESIDENT (tmp)) + saw_nonresident = 1; + if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level) + { + if (xmlsec_lt_dlclose (tmp)) + { + ++errors; + } + } + } + /* done if only resident modules are left */ + if (!saw_nonresident) + break; + } + + /* close all loaders */ + while (loader) + { + xmlsec_lt_dlloader *next = loader->next; + xmlsec_lt_user_data data = loader->dlloader_data; + if (loader->dlloader_exit && loader->dlloader_exit (data)) + { + ++errors; + } + + LT_DLMEM_REASSIGN (loader, next); + } + loaders = NULL; + } + + done: + LT_DLMUTEX_UNLOCK (); + return errors; +} + +static int +tryall_dlopen (handle, filename) + xmlsec_lt_dlhandle *handle; + const char *filename; +{ + xmlsec_lt_dlhandle cur; + xmlsec_lt_dlloader *loader; + const char *saved_error; + int errors = 0; + + LT_DLMUTEX_GETERROR (saved_error); + LT_DLMUTEX_LOCK (); + + cur = handles; + loader = loaders; + + /* check whether the module was already opened */ + while (cur) + { + /* try to dlopen the program itself? */ + if (!cur->info.filename && !filename) + { + break; + } + + if (cur->info.filename && filename + && strcmp (cur->info.filename, filename) == 0) + { + break; + } + + cur = cur->next; + } + + if (cur) + { + ++cur->info.ref_count; + *handle = cur; + goto done; + } + + cur = *handle; + if (filename) + { + cur->info.filename = xmlsec_lt_estrdup (filename); + if (!cur->info.filename) + { + ++errors; + goto done; + } + } + else + { + cur->info.filename = NULL; + } + + while (loader) + { + xmlsec_lt_user_data data = loader->dlloader_data; + + cur->module = loader->module_open (data, filename); + + if (cur->module != NULL) + { + break; + } + loader = loader->next; + } + + if (!loader) + { + LT_DLFREE (cur->info.filename); + ++errors; + goto done; + } + + cur->loader = loader; + LT_DLMUTEX_SETERROR (saved_error); + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static int +tryall_dlopen_module (handle, prefix, dirname, dlname) + xmlsec_lt_dlhandle *handle; + const char *prefix; + const char *dirname; + const char *dlname; +{ + int error = 0; + char *filename = NULL; + size_t filename_len = 0; + size_t dirname_len = LT_STRLEN (dirname); + + assert (handle); + assert (dirname); + assert (dlname); +#ifdef LT_DIRSEP_CHAR + /* Only canonicalized names (i.e. with DIRSEP chars already converted) + should make it into this function: */ + assert (strchr (dirname, LT_DIRSEP_CHAR) == NULL); +#endif + + if (dirname[dirname_len -1] == '/') + --dirname_len; + filename_len = dirname_len + 1 + LT_STRLEN (dlname); + + /* Allocate memory, and combine DIRNAME and MODULENAME into it. + The PREFIX (if any) is handled below. */ + filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1); + if (!filename) + return 1; + + sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname); + + /* Now that we have combined DIRNAME and MODULENAME, if there is + also a PREFIX to contend with, simply recurse with the arguments + shuffled. Otherwise, attempt to open FILENAME as a module. */ + if (prefix) + { + error += tryall_dlopen_module (handle, + (const char *) 0, prefix, filename); + } + else if (tryall_dlopen (handle, filename) != 0) + { + ++error; + } + + LT_DLFREE (filename); + return error; +} + +static int +find_module (handle, dir, libdir, dlname, old_name, installed) + xmlsec_lt_dlhandle *handle; + const char *dir; + const char *libdir; + const char *dlname; + const char *old_name; + int installed; +{ + /* Try to open the old library first; if it was dlpreopened, + we want the preopened version of it, even if a dlopenable + module is available. */ + if (old_name && tryall_dlopen (handle, old_name) == 0) + { + return 0; + } + + /* Try to open the dynamic library. */ + if (dlname) + { + /* try to open the installed module */ + if (installed && libdir) + { + if (tryall_dlopen_module (handle, + (const char *) 0, libdir, dlname) == 0) + return 0; + } + + /* try to open the not-installed module */ + if (!installed) + { + if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0) + return 0; + } + + /* maybe it was moved to another directory */ + { + if (tryall_dlopen_module (handle, + (const char *) 0, dir, dlname) == 0) + return 0; + } + } + + return 1; +} + + +static int +canonicalize_path (path, pcanonical) + const char *path; + char **pcanonical; +{ + char *canonical = NULL; + + assert (path && *path); + assert (pcanonical); + + canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path)); + if (!canonical) + return 1; + + { + size_t dest = 0; + size_t src; + for (src = 0; path[src] != LT_EOS_CHAR; ++src) + { + /* Path separators are not copied to the beginning or end of + the destination, or if another separator would follow + immediately. */ + if (path[src] == LT_PATHSEP_CHAR) + { + if ((dest == 0) + || (path[1+ src] == LT_PATHSEP_CHAR) + || (path[1+ src] == LT_EOS_CHAR)) + continue; + } + + /* Anything other than a directory separator is copied verbatim. */ + if ((path[src] != '/') +#ifdef LT_DIRSEP_CHAR + && (path[src] != LT_DIRSEP_CHAR) +#endif + ) + { + canonical[dest++] = path[src]; + } + /* Directory separators are converted and copied only if they are + not at the end of a path -- i.e. before a path separator or + NULL terminator. */ + else if ((path[1+ src] != LT_PATHSEP_CHAR) + && (path[1+ src] != LT_EOS_CHAR) +#ifdef LT_DIRSEP_CHAR + && (path[1+ src] != LT_DIRSEP_CHAR) +#endif + && (path[1+ src] != '/')) + { + canonical[dest++] = '/'; + } + } + + /* Add an end-of-string marker at the end. */ + canonical[dest] = LT_EOS_CHAR; + } + + /* Assign new value. */ + *pcanonical = canonical; + + return 0; +} + +static int +argzize_path (path, pargz, pargz_len) + const char *path; + char **pargz; + size_t *pargz_len; +{ + error_t error; + + assert (path); + assert (pargz); + assert (pargz_len); + + if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len))) + { + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + + return 1; + } + + return 0; +} + +/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element + of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns + non-zero or all elements are exhausted. If BASE_NAME is non-NULL, + it is appended to each SEARCH_PATH element before FUNC is called. */ +static int +foreach_dirinpath (search_path, base_name, func, data1, data2) + const char *search_path; + const char *base_name; + foreach_callback_func *func; + xmlsec_lt_ptr data1; + xmlsec_lt_ptr data2; +{ + int result = 0; + int filenamesize = 0; + size_t lenbase = LT_STRLEN (base_name); + size_t argz_len = 0; + char *argz = NULL; + char *filename = NULL; + char *canonical = NULL; + + LT_DLMUTEX_LOCK (); + + if (!search_path || !*search_path) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + goto cleanup; + } + + if (canonicalize_path (search_path, &canonical) != 0) + goto cleanup; + + if (argzize_path (canonical, &argz, &argz_len) != 0) + goto cleanup; + + { + char *dir_name = NULL; + while ((dir_name = argz_next (argz, argz_len, dir_name))) + { + size_t lendir = LT_STRLEN (dir_name); + + if (lendir +1 +lenbase >= filenamesize) + { + LT_DLFREE (filename); + filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */ + filename = LT_EMALLOC (char, filenamesize); + if (!filename) + goto cleanup; + } + + assert (filenamesize > lendir); + strcpy (filename, dir_name); + + if (base_name && *base_name) + { + if (filename[lendir -1] != '/') + filename[lendir++] = '/'; + strcpy (filename +lendir, base_name); + } + + if ((result = (*func) (filename, data1, data2))) + { + break; + } + } + } + + cleanup: + LT_DLFREE (argz); + LT_DLFREE (canonical); + LT_DLFREE (filename); + + LT_DLMUTEX_UNLOCK (); + + return result; +} + +/* If FILEPATH can be opened, store the name of the directory component + in DATA1, and the opened FILE* structure address in DATA2. Otherwise + DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */ +static int +find_file_callback (filename, data1, data2) + char *filename; + xmlsec_lt_ptr data1; + xmlsec_lt_ptr data2; +{ + char **pdir = (char **) data1; + FILE **pfile = (FILE **) data2; + int is_done = 0; + + assert (filename && *filename); + assert (pdir); + assert (pfile); + + if ((*pfile = fopen (filename, LT_READTEXT_MODE))) + { + char *dirend = strrchr (filename, '/'); + + if (dirend > filename) + *dirend = LT_EOS_CHAR; + + LT_DLFREE (*pdir); + *pdir = xmlsec_lt_estrdup (filename); + is_done = (*pdir == NULL) ? -1 : 1; + } + + return is_done; +} + +static FILE * +find_file (search_path, base_name, pdir) + const char *search_path; + const char *base_name; + char **pdir; +{ + FILE *file = NULL; + + foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file); + + return file; +} + +static int +find_handle_callback (filename, data, ignored) + char *filename; + xmlsec_lt_ptr data; + xmlsec_lt_ptr ignored; +{ + xmlsec_lt_dlhandle *handle = (xmlsec_lt_dlhandle *) data; + int notfound = access (filename, R_OK); + + /* Bail out if file cannot be read... */ + if (notfound) + return 0; + + /* Try to dlopen the file, but do not continue searching in any + case. */ + if (tryall_dlopen (handle, filename) != 0) + *handle = NULL; + + return 1; +} + +/* If HANDLE was found return it, otherwise return 0. If HANDLE was + found but could not be opened, *HANDLE will be set to 0. */ +static xmlsec_lt_dlhandle * +find_handle (search_path, base_name, handle) + const char *search_path; + const char *base_name; + xmlsec_lt_dlhandle *handle; +{ + if (!search_path) + return 0; + + if (!foreach_dirinpath (search_path, base_name, find_handle_callback, + handle, 0)) + return 0; + + return handle; +} + +static int +load_deplibs (handle, deplibs) + xmlsec_lt_dlhandle handle; + char *deplibs; +{ +#if LTDL_DLOPEN_DEPLIBS + char *p, *save_search_path = NULL; + int depcount = 0; + int i; + char **names = NULL; +#endif + int errors = 0; + + handle->depcount = 0; + +#if LTDL_DLOPEN_DEPLIBS + if (!deplibs) + { + return errors; + } + ++errors; + + LT_DLMUTEX_LOCK (); + if (user_search_path) + { + save_search_path = xmlsec_lt_estrdup (user_search_path); + if (!save_search_path) + goto cleanup; + } + + /* extract search paths and count deplibs */ + p = deplibs; + while (*p) + { + if (!isspace ((int) *p)) + { + char *end = p+1; + while (*end && !isspace((int) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0) + { + char save = *end; + *end = '\0'; /* set a temporary string terminator */ + if (xmlsec_lt_dladdsearchdir(p+2)) + { + goto cleanup; + } + *end = save; + } + else + { + ++depcount; + } + + p = end; + } + else + { + ++p; + } + } + + /* restore the old search path */ + LT_DLFREE (user_search_path); + user_search_path = save_search_path; + + LT_DLMUTEX_UNLOCK (); + + if (!depcount) + { + errors = 0; + goto cleanup; + } + + names = LT_EMALLOC (char *, depcount * sizeof (char*)); + if (!names) + goto cleanup; + + /* now only extract the actual deplibs */ + depcount = 0; + p = deplibs; + while (*p) + { + if (isspace ((int) *p)) + { + ++p; + } + else + { + char *end = p+1; + while (*end && !isspace ((int) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0) + { + char *name; + char save = *end; + *end = '\0'; /* set a temporary string terminator */ + if (strncmp(p, "-l", 2) == 0) + { + size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); + name = LT_EMALLOC (char, 1+ name_len); + if (name) + sprintf (name, "lib%s", p+2); + } + else + name = xmlsec_lt_estrdup(p); + + if (!name) + goto cleanup_names; + + names[depcount++] = name; + *end = save; + } + p = end; + } + } + + /* load the deplibs (in reverse order) + At this stage, don't worry if the deplibs do not load correctly, + they may already be statically linked into the loading application + for instance. There will be a more enlightening error message + later on if the loaded module cannot resolve all of its symbols. */ + if (depcount) + { + int j = 0; + + handle->deplibs = (xmlsec_lt_dlhandle*) LT_EMALLOC (xmlsec_lt_dlhandle *, depcount); + if (!handle->deplibs) + goto cleanup; + + for (i = 0; i < depcount; ++i) + { + handle->deplibs[j] = xmlsec_lt_dlopenext(names[depcount-1-i]); + if (handle->deplibs[j]) + { + ++j; + } + } + + handle->depcount = j; /* Number of successfully loaded deplibs */ + errors = 0; + } + + cleanup_names: + for (i = 0; i < depcount; ++i) + { + LT_DLFREE (names[i]); + } + + cleanup: + LT_DLFREE (names); +#endif + + return errors; +} + +static int +unload_deplibs (handle) + xmlsec_lt_dlhandle handle; +{ + int i; + int errors = 0; + + if (handle->depcount) + { + for (i = 0; i < handle->depcount; ++i) + { + if (!LT_DLIS_RESIDENT (handle->deplibs[i])) + { + errors += xmlsec_lt_dlclose (handle->deplibs[i]); + } + } + } + + return errors; +} + +static int +trim (dest, str) + char **dest; + const char *str; +{ + /* remove the leading and trailing "'" from str + and store the result in dest */ + const char *end = strrchr (str, '\''); + size_t len = LT_STRLEN (str); + char *tmp; + + LT_DLFREE (*dest); + + if (len > 3 && str[0] == '\'') + { + tmp = LT_EMALLOC (char, end - str); + if (!tmp) + return 1; + + strncpy(tmp, &str[1], (end - str) - 1); + tmp[len-3] = LT_EOS_CHAR; + *dest = tmp; + } + else + { + *dest = NULL; + } + + return 0; +} + +static int +free_vars (dlname, oldname, libdir, deplibs) + char *dlname; + char *oldname; + char *libdir; + char *deplibs; +{ + LT_DLFREE (dlname); + LT_DLFREE (oldname); + LT_DLFREE (libdir); + LT_DLFREE (deplibs); + + return 0; +} + +static int +try_dlopen (phandle, filename) + xmlsec_lt_dlhandle *phandle; + const char *filename; +{ + const char * ext = NULL; + const char * saved_error = NULL; + char * canonical = NULL; + char * base_name = NULL; + char * dir = NULL; + char * name = NULL; + int errors = 0; + xmlsec_lt_dlhandle newhandle; + + assert (phandle); + assert (*phandle == NULL); + + LT_DLMUTEX_GETERROR (saved_error); + + /* dlopen self? */ + if (!filename) + { + *phandle = (xmlsec_lt_dlhandle) LT_EMALLOC (struct xmlsec_lt_dlhandle_struct, 1); + if (*phandle == NULL) + return 1; + + memset (*phandle, 0, sizeof(struct xmlsec_lt_dlhandle_struct)); + newhandle = *phandle; + + /* xmlsec_lt_dlclose()ing yourself is very bad! Disallow it. */ + LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG); + + if (tryall_dlopen (&newhandle, 0) != 0) + { + LT_DLFREE (*phandle); + return 1; + } + + goto register_handle; + } + + assert (filename && *filename); + + /* Doing this immediately allows internal functions to safely + assume only canonicalized paths are passed. */ + if (canonicalize_path (filename, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + /* If the canonical module name is a path (relative or absolute) + then split it into a directory part and a name part. */ + base_name = strrchr (canonical, '/'); + if (base_name) + { + size_t dirlen = (1+ base_name) - canonical; + + dir = LT_EMALLOC (char, 1+ dirlen); + if (!dir) + { + ++errors; + goto cleanup; + } + + strncpy (dir, canonical, dirlen); + dir[dirlen] = LT_EOS_CHAR; + + ++base_name; + } + else + LT_DLMEM_REASSIGN (base_name, canonical); + + assert (base_name && *base_name); + + /* Check whether we are opening a libtool module (.la extension). */ + ext = strrchr (base_name, '.'); + if (ext && strcmp (ext, archive_ext) == 0) + { + /* this seems to be a libtool module */ + FILE * file = NULL; + char * dlname = NULL; + char * old_name = NULL; + char * libdir = NULL; + char * deplibs = NULL; + char * line = NULL; + size_t line_len; + + /* if we can't find the installed flag, it is probably an + installed libtool archive, produced with an old version + of libtool */ + int installed = 1; + + /* extract the module name from the file name */ + name = LT_EMALLOC (char, ext - base_name + 1); + if (!name) + { + ++errors; + goto cleanup; + } + + /* canonicalize the module name */ + { + size_t i; + for (i = 0; i < ext - base_name; ++i) + { + if (isalnum ((int)(base_name[i]))) + { + name[i] = base_name[i]; + } + else + { + name[i] = '_'; + } + } + name[ext - base_name] = LT_EOS_CHAR; + } + + /* Now try to open the .la file. If there is no directory name + component, try to find it first in user_search_path and then other + prescribed paths. Otherwise (or in any case if the module was not + yet found) try opening just the module name as passed. */ + if (!dir) + { + const char *search_path; + + LT_DLMUTEX_LOCK (); + search_path = user_search_path; + if (search_path) + file = find_file (user_search_path, base_name, &dir); + LT_DLMUTEX_UNLOCK (); + + if (!file) + { + search_path = getenv (LTDL_SEARCHPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } + +#ifdef LTDL_SHLIBPATH_VAR + if (!file) + { + search_path = getenv (LTDL_SHLIBPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } +#endif +#ifdef LTDL_SYSSEARCHPATH + if (!file && sys_search_path) + { + file = find_file (sys_search_path, base_name, &dir); + } +#endif + } + if (!file) + { + file = fopen (filename, LT_READTEXT_MODE); + } + + /* If we didn't find the file by now, it really isn't there. Set + the status flag, and bail out. */ + if (!file) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + ++errors; + goto cleanup; + } + + line_len = LT_FILENAME_MAX; + line = LT_EMALLOC (char, line_len); + if (!line) + { + fclose (file); + ++errors; + goto cleanup; + } + + /* read the .la file */ + while (!feof (file)) + { + if (!fgets (line, (int) line_len, file)) + { + break; + } + + /* Handle the case where we occasionally need to read a line + that is longer than the initial buffer size. */ + while (line[LT_STRLEN(line) -1] != '\n') + { + line = LT_DLREALLOC (char, line, line_len *2); + if (!fgets (&line[line_len -1], (int) line_len +1, file)) + { + break; + } + line_len *= 2; + } + + if (line[0] == '\n' || line[0] == '#') + { + continue; + } + +#undef STR_DLNAME +#define STR_DLNAME "dlname=" + if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) + { + errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); + } + +#undef STR_OLD_LIBRARY +#define STR_OLD_LIBRARY "old_library=" + else if (strncmp (line, STR_OLD_LIBRARY, + sizeof (STR_OLD_LIBRARY) - 1) == 0) + { + errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); + } +#undef STR_LIBDIR +#define STR_LIBDIR "libdir=" + else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) + { + errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); + } + +#undef STR_DL_DEPLIBS +#define STR_DL_DEPLIBS "dependency_libs=" + else if (strncmp (line, STR_DL_DEPLIBS, + sizeof (STR_DL_DEPLIBS) - 1) == 0) + { + errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); + } + else if (strcmp (line, "installed=yes\n") == 0) + { + installed = 1; + } + else if (strcmp (line, "installed=no\n") == 0) + { + installed = 0; + } + +#undef STR_LIBRARY_NAMES +#define STR_LIBRARY_NAMES "library_names=" + else if (! dlname && strncmp (line, STR_LIBRARY_NAMES, + sizeof (STR_LIBRARY_NAMES) - 1) == 0) + { + char *last_libname; + errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); + if (!errors + && dlname + && (last_libname = strrchr (dlname, ' ')) != NULL) + { + last_libname = xmlsec_lt_estrdup (last_libname + 1); + if (!last_libname) + { + ++errors; + goto cleanup; + } + LT_DLMEM_REASSIGN (dlname, last_libname); + } + } + + if (errors) + break; + } + + fclose (file); + LT_DLFREE (line); + + /* allocate the handle */ + *phandle = (xmlsec_lt_dlhandle) LT_EMALLOC (struct xmlsec_lt_dlhandle_struct, 1); + if (*phandle == NULL) + ++errors; + + if (errors) + { + free_vars (dlname, old_name, libdir, deplibs); + LT_DLFREE (*phandle); + goto cleanup; + } + + assert (*phandle); + + memset (*phandle, 0, sizeof(struct xmlsec_lt_dlhandle_struct)); + if (load_deplibs (*phandle, deplibs) == 0) + { + newhandle = *phandle; + /* find_module may replace newhandle */ + if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) + { + unload_deplibs (*phandle); + ++errors; + } + } + else + { + ++errors; + } + + free_vars (dlname, old_name, libdir, deplibs); + if (errors) + { + LT_DLFREE (*phandle); + goto cleanup; + } + + if (*phandle != newhandle) + { + unload_deplibs (*phandle); + } + } + else + { + /* not a libtool module */ + *phandle = (xmlsec_lt_dlhandle) LT_EMALLOC (struct xmlsec_lt_dlhandle_struct, 1); + if (*phandle == NULL) + { + ++errors; + goto cleanup; + } + + memset (*phandle, 0, sizeof (struct xmlsec_lt_dlhandle_struct)); + newhandle = *phandle; + + /* If the module has no directory name component, try to find it + first in user_search_path and then other prescribed paths. + Otherwise (or in any case if the module was not yet found) try + opening just the module name as passed. */ + if ((dir || (!find_handle (user_search_path, base_name, &newhandle) + && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, + &newhandle) +#ifdef LTDL_SHLIBPATH_VAR + && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name, + &newhandle) +#endif +#ifdef LTDL_SYSSEARCHPATH + && !find_handle (sys_search_path, base_name, &newhandle) +#endif + ))) + { + if (tryall_dlopen (&newhandle, filename) != 0) + { + newhandle = NULL; + } + } + + if (!newhandle) + { + LT_DLFREE (*phandle); + ++errors; + goto cleanup; + } + } + + register_handle: + LT_DLMEM_REASSIGN (*phandle, newhandle); + + if ((*phandle)->info.ref_count == 0) + { + (*phandle)->info.ref_count = 1; + LT_DLMEM_REASSIGN ((*phandle)->info.name, name); + + LT_DLMUTEX_LOCK (); + (*phandle)->next = handles; + handles = *phandle; + LT_DLMUTEX_UNLOCK (); + } + + LT_DLMUTEX_SETERROR (saved_error); + + cleanup: + LT_DLFREE (dir); + LT_DLFREE (name); + LT_DLFREE (canonical); + + return errors; +} + +xmlsec_lt_dlhandle +xmlsec_lt_dlopen (filename) + const char *filename; +{ + xmlsec_lt_dlhandle handle = NULL; + + /* Just incase we missed a code path in try_dlopen() that reports + an error, but forgets to reset handle... */ + if (try_dlopen (&handle, filename) != 0) + return 0; + + return handle; +} + +/* If the last error messge store was `FILE_NOT_FOUND', then return + non-zero. */ +static int +file_not_found () +{ + const char *error = NULL; + + LT_DLMUTEX_GETERROR (error); + if (error == LT_DLSTRERROR (FILE_NOT_FOUND)) + return 1; + + return 0; +} + +/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to + open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, + and if a file is still not found try again with SHLIB_EXT appended + instead. */ +xmlsec_lt_dlhandle +xmlsec_lt_dlopenext (filename) + const char *filename; +{ + xmlsec_lt_dlhandle handle = NULL; + char * tmp = NULL; + char * ext = NULL; + size_t len; + int errors = 0; + + if (!filename) + { + return xmlsec_lt_dlopen (filename); + } + + assert (filename); + + len = LT_STRLEN (filename); + ext = strrchr (filename, '.'); + + /* If FILENAME already bears a suitable extension, there is no need + to try appending additional extensions. */ + if (ext && ((strcmp (ext, archive_ext) == 0) +#ifdef LTDL_SHLIB_EXT + || (strcmp (ext, shlib_ext) == 0) +#endif + )) + { + return xmlsec_lt_dlopen (filename); + } + + /* First try appending ARCHIVE_EXT. */ + tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1); + if (!tmp) + return 0; + + strcpy (tmp, filename); + strcat (tmp, archive_ext); + errors = try_dlopen (&handle, tmp); + + /* If we found FILENAME, stop searching -- whether we were able to + load the file as a module or not. If the file exists but loading + failed, it is better to return an error message here than to + report FILE_NOT_FOUND when the alternatives (foo.so etc) are not + in the module search path. */ + if (handle || ((errors > 0) && file_not_found ())) + { + LT_DLFREE (tmp); + return handle; + } + +#ifdef LTDL_SHLIB_EXT + /* Try appending SHLIB_EXT. */ + if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext)) + { + LT_DLFREE (tmp); + tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1); + if (!tmp) + return 0; + + strcpy (tmp, filename); + } + else + { + tmp[len] = LT_EOS_CHAR; + } + + strcat(tmp, shlib_ext); + errors = try_dlopen (&handle, tmp); + + /* As before, if the file was found but loading failed, return now + with the current error message. */ + if (handle || ((errors > 0) && file_not_found ())) + { + LT_DLFREE (tmp); + return handle; + } +#endif + + /* Still here? Then we really did fail to locate any of the file + names we tried. */ + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + LT_DLFREE (tmp); + return 0; +} + + +static int +xmlsec_lt_argz_insert (pargz, pargz_len, before, entry) + char **pargz; + size_t *pargz_len; + char *before; + const char *entry; +{ + error_t error; + + if ((error = argz_insert (pargz, pargz_len, before, entry))) + { + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + return 1; + } + + return 0; +} + +static int +xmlsec_lt_argz_insertinorder (pargz, pargz_len, entry) + char **pargz; + size_t *pargz_len; + const char *entry; +{ + char *before = NULL; + + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + if (*pargz) + while ((before = argz_next (*pargz, *pargz_len, before))) + { + int cmp = strcmp (entry, before); + + if (cmp < 0) break; + if (cmp == 0) return 0; /* No duplicates! */ + } + + return xmlsec_lt_argz_insert (pargz, pargz_len, before, entry); +} + +static int +xmlsec_lt_argz_insertdir (pargz, pargz_len, dirnam, dp) + char **pargz; + size_t *pargz_len; + const char *dirnam; + struct dirent *dp; +{ + char *buf = NULL; + size_t buf_len = 0; + char *end = NULL; + size_t end_offset = 0; + size_t dir_len = 0; + int errors = 0; + + assert (pargz); + assert (pargz_len); + assert (dp); + + dir_len = LT_STRLEN (dirnam); + end = dp->d_name + LT_D_NAMLEN(dp); + + /* Ignore version numbers. */ + { + char *p; + for (p = end; p -1 > dp->d_name; --p) + if (strchr (".0123456789", p[-1]) == 0) + break; + + if (*p == '.') + end = p; + } + + /* Ignore filename extension. */ + { + char *p; + for (p = end -1; p > dp->d_name; --p) + if (*p == '.') + { + end = p; + break; + } + } + + /* Prepend the directory name. */ + end_offset = end - dp->d_name; + buf_len = dir_len + 1+ end_offset; + buf = LT_EMALLOC (char, 1+ buf_len); + if (!buf) + return ++errors; + + assert (buf); + + strcpy (buf, dirnam); + strcat (buf, "/"); + strncat (buf, dp->d_name, end_offset); + buf[buf_len] = LT_EOS_CHAR; + + /* Try to insert (in order) into ARGZ/ARGZ_LEN. */ + if (xmlsec_lt_argz_insertinorder (pargz, pargz_len, buf) != 0) + ++errors; + + LT_DLFREE (buf); + + return errors; +} + +static int +list_files_by_dir (dirnam, pargz, pargz_len) + const char *dirnam; + char **pargz; + size_t *pargz_len; +{ + DIR *dirp = NULL; + int errors = 0; + + assert (dirnam && *dirnam); + assert (pargz); + assert (pargz_len); + assert (dirnam[LT_STRLEN(dirnam) -1] != '/'); + + dirp = opendir (dirnam); + if (dirp) + { + struct dirent *dp = NULL; + + while ((dp = readdir (dirp))) + if (dp->d_name[0] != '.') + if (xmlsec_lt_argz_insertdir (pargz, pargz_len, dirnam, dp)) + { + ++errors; + break; + } + + closedir (dirp); + } + else + ++errors; + + return errors; +} + + +/* If there are any files in DIRNAME, call the function passed in + DATA1 (with the name of each file and DATA2 as arguments). */ +static int +foreachfile_callback (dirname, data1, data2) + char *dirname; + xmlsec_lt_ptr data1; + xmlsec_lt_ptr data2; +{ + int (*func) LT_PARAMS((const char *filename, xmlsec_lt_ptr data)) + = (int (*) LT_PARAMS((const char *filename, xmlsec_lt_ptr data))) data1; + + int is_done = 0; + char *argz = NULL; + size_t argz_len = 0; + + if (list_files_by_dir (dirname, &argz, &argz_len) != 0) + goto cleanup; + if (!argz) + goto cleanup; + + { + char *filename = NULL; + while ((filename = argz_next (argz, argz_len, filename))) + if ((is_done = (*func) (filename, data2))) + break; + } + + cleanup: + LT_DLFREE (argz); + + return is_done; +} + + +/* Call FUNC for each unique extensionless file in SEARCH_PATH, along + with DATA. The filenames passed to FUNC would be suitable for + passing to xmlsec_lt_dlopenext. The extensions are stripped so that + individual modules do not generate several entries (e.g. libfoo.la, + libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL, + then the same directories that xmlsec_lt_dlopen would search are examined. */ +int +xmlsec_lt_dlforeachfile (search_path, func, data) + const char *search_path; + int (*func) LT_PARAMS ((const char *filename, xmlsec_lt_ptr data)); + xmlsec_lt_ptr data; +{ + int is_done = 0; + + if (search_path) + { + /* If a specific path was passed, search only the directories + listed in it. */ + is_done = foreach_dirinpath (search_path, 0, + (xmlsec_lt_ptr)foreachfile_callback, func, data); + } + else + { + /* Otherwise search the default paths. */ + is_done = foreach_dirinpath (user_search_path, 0, + (xmlsec_lt_ptr)foreachfile_callback, func, data); + if (!is_done) + { + is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0, + (xmlsec_lt_ptr)foreachfile_callback, func, data); + } + +#ifdef LTDL_SHLIBPATH_VAR + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0, + (xmlsec_lt_ptr)foreachfile_callback, func, data); + } +#endif +#ifdef LTDL_SYSSEARCHPATH + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0, + (xmlsec_lt_ptr)foreachfile_callback, func, data); + } +#endif + } + + return is_done; +} + +int +xmlsec_lt_dlclose (handle) + xmlsec_lt_dlhandle handle; +{ + xmlsec_lt_dlhandle cur, last; + int errors = 0; + + LT_DLMUTEX_LOCK (); + + /* check whether the handle is valid */ + last = cur = handles; + while (cur && handle != cur) + { + last = cur; + cur = cur->next; + } + + if (!cur) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + ++errors; + goto done; + } + + handle->info.ref_count--; + + /* Note that even with resident modules, we must track the ref_count + correctly incase the user decides to reset the residency flag + later (even though the API makes no provision for that at the + moment). */ + if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle)) + { + xmlsec_lt_user_data data = handle->loader->dlloader_data; + + if (handle != handles) + { + last->next = handle->next; + } + else + { + handles = handle->next; + } + + errors += handle->loader->module_close (data, handle->module); + errors += unload_deplibs(handle); + + /* It is up to the callers to free the data itself. */ + LT_DLFREE (handle->caller_data); + + LT_DLFREE (handle->info.filename); + LT_DLFREE (handle->info.name); + LT_DLFREE (handle); + + goto done; + } + + if (LT_DLIS_RESIDENT (handle)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE)); + ++errors; + } + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +xmlsec_lt_ptr +xmlsec_lt_dlsym (handle, symbol) + xmlsec_lt_dlhandle handle; + const char *symbol; +{ + size_t lensym; + char lsym[LT_SYMBOL_LENGTH]; + char *sym; + xmlsec_lt_ptr address; + xmlsec_lt_user_data data; + + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return 0; + } + + if (!symbol) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + return 0; + } + + lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix) + + LT_STRLEN (handle->info.name); + + if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH) + { + sym = lsym; + } + else + { + sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); + if (!sym) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW)); + return 0; + } + } + + data = handle->loader->dlloader_data; + if (handle->info.name) + { + const char *saved_error; + + LT_DLMUTEX_GETERROR (saved_error); + + /* this is a libtool module */ + if (handle->loader->sym_prefix) + { + strcpy(sym, handle->loader->sym_prefix); + strcat(sym, handle->info.name); + } + else + { + strcpy(sym, handle->info.name); + } + + strcat(sym, "_LTX_"); + strcat(sym, symbol); + + /* try "modulename_LTX_symbol" */ + address = handle->loader->find_sym (data, handle->module, sym); + if (address) + { + if (sym != lsym) + { + LT_DLFREE (sym); + } + return address; + } + LT_DLMUTEX_SETERROR (saved_error); + } + + /* otherwise try "symbol" */ + if (handle->loader->sym_prefix) + { + strcpy(sym, handle->loader->sym_prefix); + strcat(sym, symbol); + } + else + { + strcpy(sym, symbol); + } + + address = handle->loader->find_sym (data, handle->module, sym); + if (sym != lsym) + { + LT_DLFREE (sym); + } + + return address; +} + +const char * +xmlsec_lt_dlerror () +{ + const char *error; + + LT_DLMUTEX_GETERROR (error); + LT_DLMUTEX_SETERROR (0); + + return error ? error : LT_DLSTRERROR (UNKNOWN); +} + +static int +xmlsec_lt_dlpath_insertdir (ppath, before, dir) + char **ppath; + char *before; + const char *dir; +{ + int errors = 0; + char *canonical = NULL; + char *argz = NULL; + size_t argz_len = 0; + + assert (ppath); + assert (dir && *dir); + + if (canonicalize_path (dir, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + assert (canonical && *canonical); + + /* If *PPATH is empty, set it to DIR. */ + if (*ppath == NULL) + { + assert (!before); /* BEFORE cannot be set without PPATH. */ + assert (dir); /* Without DIR, don't call this function! */ + + *ppath = xmlsec_lt_estrdup (dir); + if (*ppath == NULL) + ++errors; + + return errors; + } + + assert (ppath && *ppath); + + if (argzize_path (*ppath, &argz, &argz_len) != 0) + { + ++errors; + goto cleanup; + } + + /* Convert BEFORE into an equivalent offset into ARGZ. This only works + if *PPATH is already canonicalized, and hence does not change length + with respect to ARGZ. We canonicalize each entry as it is added to + the search path, and don't call this function with (uncanonicalized) + user paths, so this is a fair assumption. */ + if (before) + { + assert (*ppath <= before); + assert (before - *ppath <= strlen (*ppath)); + + before = before - *ppath + argz; + } + + if (xmlsec_lt_argz_insert (&argz, &argz_len, before, dir) != 0) + { + ++errors; + goto cleanup; + } + + argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); + LT_DLMEM_REASSIGN (*ppath, argz); + + cleanup: + LT_DLFREE (canonical); + LT_DLFREE (argz); + + return errors; +} + +int +xmlsec_lt_dladdsearchdir (search_dir) + const char *search_dir; +{ + int errors = 0; + + if (search_dir && *search_dir) + { + LT_DLMUTEX_LOCK (); + if (xmlsec_lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0) + ++errors; + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +xmlsec_lt_dlinsertsearchdir (before, search_dir) + const char *before; + const char *search_dir; +{ + int errors = 0; + + if (before) + { + LT_DLMUTEX_LOCK (); + if ((before < user_search_path) + || (before >= user_search_path + LT_STRLEN (user_search_path))) + { + LT_DLMUTEX_UNLOCK (); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION)); + return 1; + } + LT_DLMUTEX_UNLOCK (); + } + + if (search_dir && *search_dir) + { + LT_DLMUTEX_LOCK (); + if (xmlsec_lt_dlpath_insertdir (&user_search_path, + (char *) before, search_dir) != 0) + { + ++errors; + } + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +xmlsec_lt_dlsetsearchpath (search_path) + const char *search_path; +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + LT_DLFREE (user_search_path); + LT_DLMUTEX_UNLOCK (); + + if (!search_path || !LT_STRLEN (search_path)) + { + return errors; + } + + LT_DLMUTEX_LOCK (); + if (canonicalize_path (search_path, &user_search_path) != 0) + ++errors; + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +const char * +xmlsec_lt_dlgetsearchpath () +{ + const char *saved_path; + + LT_DLMUTEX_LOCK (); + saved_path = user_search_path; + LT_DLMUTEX_UNLOCK (); + + return saved_path; +} + +int +xmlsec_lt_dlmakeresident (handle) + xmlsec_lt_dlhandle handle; +{ + int errors = 0; + + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + ++errors; + } + else + { + LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); + } + + return errors; +} + +int +xmlsec_lt_dlisresident (handle) + xmlsec_lt_dlhandle handle; +{ + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return -1; + } + + return LT_DLIS_RESIDENT (handle); +} + + + + +/* --- MODULE INFORMATION --- */ + +const xmlsec_lt_dlinfo * +xmlsec_lt_dlgetinfo (handle) + xmlsec_lt_dlhandle handle; +{ + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return 0; + } + + return &(handle->info); +} + +xmlsec_lt_dlhandle +xmlsec_lt_dlhandle_next (place) + xmlsec_lt_dlhandle place; +{ + return place ? place->next : handles; +} + +int +xmlsec_lt_dlforeach (func, data) + int (*func) LT_PARAMS((xmlsec_lt_dlhandle handle, xmlsec_lt_ptr data)); + xmlsec_lt_ptr data; +{ + int errors = 0; + xmlsec_lt_dlhandle cur; + + LT_DLMUTEX_LOCK (); + + cur = handles; + while (cur) + { + xmlsec_lt_dlhandle tmp = cur; + + cur = cur->next; + if ((*func) (tmp, data)) + { + ++errors; + break; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +xmlsec_lt_dlcaller_id +xmlsec_lt_dlcaller_register () +{ + static xmlsec_lt_dlcaller_id last_caller_id = 0; + int result; + + LT_DLMUTEX_LOCK (); + result = ++last_caller_id; + LT_DLMUTEX_UNLOCK (); + + return result; +} + +xmlsec_lt_ptr +xmlsec_lt_dlcaller_set_data (key, handle, data) + xmlsec_lt_dlcaller_id key; + xmlsec_lt_dlhandle handle; + xmlsec_lt_ptr data; +{ + int n_elements = 0; + xmlsec_lt_ptr stale = NULL; + int i; + + /* This needs to be locked so that the caller data can be updated + simultaneously by different threads. */ + LT_DLMUTEX_LOCK (); + + if (handle->caller_data) + while (handle->caller_data[n_elements].key) + ++n_elements; + + for (i = 0; i < n_elements; ++i) + { + if (handle->caller_data[i].key == key) + { + stale = handle->caller_data[i].data; + break; + } + } + + /* Ensure that there is enough room in this handle's caller_data + array to accept a new element (and an empty end marker). */ + if (i == n_elements) + { + xmlsec_lt_caller_data *temp + = LT_DLREALLOC (xmlsec_lt_caller_data, handle->caller_data, 2+ n_elements); + + if (!temp) + { + stale = NULL; + goto done; + } + + handle->caller_data = temp; + + /* We only need this if we needed to allocate a new caller_data. */ + handle->caller_data[i].key = key; + handle->caller_data[1+ i].key = 0; + } + + handle->caller_data[i].data = data; + + done: + LT_DLMUTEX_UNLOCK (); + + return stale; +} + +xmlsec_lt_ptr +xmlsec_lt_dlcaller_get_data (key, handle) + xmlsec_lt_dlcaller_id key; + xmlsec_lt_dlhandle handle; +{ + xmlsec_lt_ptr result = (xmlsec_lt_ptr) 0; + + /* This needs to be locked so that the caller data isn't updated by + another thread part way through this function. */ + LT_DLMUTEX_LOCK (); + + /* Locate the index of the element with a matching KEY. */ + { + int i; + for (i = 0; handle->caller_data[i].key; ++i) + { + if (handle->caller_data[i].key == key) + { + result = handle->caller_data[i].data; + break; + } + } + } + + LT_DLMUTEX_UNLOCK (); + + return result; +} + + + +/* --- USER MODULE LOADER API --- */ + + +int +xmlsec_lt_dlloader_add (place, dlloader, loader_name) + xmlsec_lt_dlloader *place; + const struct xmlsec_lt_user_dlloader *dlloader; + const char *loader_name; +{ + int errors = 0; + xmlsec_lt_dlloader *node = NULL, *ptr = NULL; + + if ((dlloader == NULL) /* diagnose null parameters */ + || (dlloader->module_open == NULL) + || (dlloader->module_close == NULL) + || (dlloader->find_sym == NULL)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + return 1; + } + + /* Create a new dlloader node with copies of the user callbacks. */ + node = LT_EMALLOC (xmlsec_lt_dlloader, 1); + if (!node) + return 1; + + node->next = NULL; + node->loader_name = loader_name; + node->sym_prefix = dlloader->sym_prefix; + node->dlloader_exit = dlloader->dlloader_exit; + node->module_open = dlloader->module_open; + node->module_close = dlloader->module_close; + node->find_sym = dlloader->find_sym; + node->dlloader_data = dlloader->dlloader_data; + + LT_DLMUTEX_LOCK (); + if (!loaders) + { + /* If there are no loaders, NODE becomes the list! */ + loaders = node; + } + else if (!place) + { + /* If PLACE is not set, add NODE to the end of the + LOADERS list. */ + for (ptr = loaders; ptr->next; ptr = ptr->next) + { + /*NOWORK*/; + } + + ptr->next = node; + } + else if (loaders == place) + { + /* If PLACE is the first loader, NODE goes first. */ + node->next = place; + loaders = node; + } + else + { + /* Find the node immediately preceding PLACE. */ + for (ptr = loaders; ptr->next != place; ptr = ptr->next) + { + /*NOWORK*/; + } + + if (ptr->next != place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + ++errors; + } + else + { + /* Insert NODE between PTR and PLACE. */ + node->next = place; + ptr->next = node; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +int +xmlsec_lt_dlloader_remove (loader_name) + const char *loader_name; +{ + xmlsec_lt_dlloader *place = xmlsec_lt_dlloader_find (loader_name); + xmlsec_lt_dlhandle handle; + int errors = 0; + + if (!place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + return 1; + } + + LT_DLMUTEX_LOCK (); + + /* Fail if there are any open modules which use this loader. */ + for (handle = handles; handle; handle = handle->next) + { + if (handle->loader == place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER)); + ++errors; + goto done; + } + } + + if (place == loaders) + { + /* PLACE is the first loader in the list. */ + loaders = loaders->next; + } + else + { + /* Find the loader before the one being removed. */ + xmlsec_lt_dlloader *prev; + for (prev = loaders; prev->next; prev = prev->next) + { + if (!strcmp (prev->next->loader_name, loader_name)) + { + break; + } + } + + place = prev->next; + prev->next = prev->next->next; + } + + if (place->dlloader_exit) + { + errors = place->dlloader_exit (place->dlloader_data); + } + + LT_DLFREE (place); + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +xmlsec_lt_dlloader * +xmlsec_lt_dlloader_next (place) + xmlsec_lt_dlloader *place; +{ + xmlsec_lt_dlloader *next; + + LT_DLMUTEX_LOCK (); + next = place ? place->next : loaders; + LT_DLMUTEX_UNLOCK (); + + return next; +} + +const char * +xmlsec_lt_dlloader_name (place) + xmlsec_lt_dlloader *place; +{ + const char *name = NULL; + + if (place) + { + LT_DLMUTEX_LOCK (); + name = place ? place->loader_name : 0; + LT_DLMUTEX_UNLOCK (); + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + } + + return name; +} + +xmlsec_lt_user_data * +xmlsec_lt_dlloader_data (place) + xmlsec_lt_dlloader *place; +{ + xmlsec_lt_user_data *data = NULL; + + if (place) + { + LT_DLMUTEX_LOCK (); + data = place ? &(place->dlloader_data) : 0; + LT_DLMUTEX_UNLOCK (); + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + } + + return data; +} + +xmlsec_lt_dlloader * +xmlsec_lt_dlloader_find (loader_name) + const char *loader_name; +{ + xmlsec_lt_dlloader *place = NULL; + + LT_DLMUTEX_LOCK (); + for (place = loaders; place; place = place->next) + { + if (strcmp (place->loader_name, loader_name) == 0) + { + break; + } + } + LT_DLMUTEX_UNLOCK (); + + return place; +} diff --git a/src/xmlsec-ltdl.c.patch b/src/xmlsec-ltdl.c.patch new file mode 100644 index 00000000..a8d09b12 --- /dev/null +++ b/src/xmlsec-ltdl.c.patch @@ -0,0 +1,39 @@ +--- xmlsec-ltdl.c.orig 2003-09-08 19:21:17.000000000 -0700 ++++ xmlsec-ltdl.c 2003-09-08 19:22:02.000000000 -0700 +@@ -3234,31 +3230,31 @@ + /* If a specific path was passed, search only the directories + listed in it. */ + is_done = foreach_dirinpath (search_path, 0, +- foreachfile_callback, func, data); ++ (xmlsec_lt_ptr)foreachfile_callback, func, data); + } + else + { + /* Otherwise search the default paths. */ + is_done = foreach_dirinpath (user_search_path, 0, +- foreachfile_callback, func, data); ++ (xmlsec_lt_ptr)foreachfile_callback, func, data); + if (!is_done) + { + is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0, +- foreachfile_callback, func, data); ++ (xmlsec_lt_ptr)foreachfile_callback, func, data); + } + + #ifdef LTDL_SHLIBPATH_VAR + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0, +- foreachfile_callback, func, data); ++ (xmlsec_lt_ptr)foreachfile_callback, func, data); + } + #endif + #ifdef LTDL_SYSSEARCHPATH + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0, +- foreachfile_callback, func, data); ++ (xmlsec_lt_ptr)foreachfile_callback, func, data); + } + #endif + } diff --git a/src/xmlsec-ltdl.h b/src/xmlsec-ltdl.h new file mode 100644 index 00000000..d4895916 --- /dev/null +++ b/src/xmlsec-ltdl.h @@ -0,0 +1,361 @@ +/* xmlsec-ltdl.h -- generic dlopen functions + Copyright (C) 1998-2000 Free Software Foundation, Inc. + Originally by Thomas Tanner <tanner@ffii.org> + This file is part of GNU Libtool. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU libtool, you may include it under the same +distribution terms that you use for the rest of that program. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA +*/ + +/* Only include this header file once. */ +#ifndef LTDL_H +#define LTDL_H 1 + +#include <sys/types.h> /* for size_t declaration */ + + +/* --- MACROS FOR PORTABILITY --- */ + + +/* Saves on those hard to debug '\0' typos.... */ +#define LT_EOS_CHAR '\0' + +/* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations, + so that C++ compilers don't mangle their names. Use LTDL_END_C_DECLS at + the end of C declarations. */ +#ifdef __cplusplus +# define LT_BEGIN_C_DECLS extern "C" { +# define LT_END_C_DECLS } +#else +# define LT_BEGIN_C_DECLS /* empty */ +# define LT_END_C_DECLS /* empty */ +#endif + +LT_BEGIN_C_DECLS + + +/* LT_PARAMS is a macro used to wrap function prototypes, so that compilers + that don't understand ANSI C prototypes still work, and ANSI C + compilers can issue warnings about type mismatches. */ +#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus) +# define LT_PARAMS(protos) protos +# define xmlsec_lt_ptr void* +#else +# define LT_PARAMS(protos) () +# define xmlsec_lt_ptr char* +#endif + +/* LT_STMT_START/END are used to create macros which expand to a + a single compound statement in a portable way. */ +#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) +# define LT_STMT_START (void)( +# define LT_STMT_END ) +#else +# if (defined (sun) || defined (__sun__)) +# define LT_STMT_START if (1) +# define LT_STMT_END else (void)0 +# else +# define LT_STMT_START do +# define LT_STMT_END while (0) +# endif +#endif + +/* LT_CONC creates a new concatenated symbol for the compiler + in a portable way. */ +#if defined(__STDC__) || defined(__cplusplus) +# define LT_CONC(s,t) s##t +#else +# define LT_CONC(s,t) s/**/t +#endif + +/* LT_STRLEN can be used safely on NULL pointers. */ +#define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) + + + +/* --- WINDOWS SUPPORT --- */ + + +/* Canonicalise Windows and Cygwin recognition macros. */ +#ifdef __CYGWIN32__ +# ifndef __CYGWIN__ +# define __CYGWIN__ __CYGWIN32__ +# endif +#endif +#if defined(_WIN32) || defined(WIN32) +# ifndef __WINDOWS__ +# ifdef _WIN32 +# define __WINDOWS__ _WIN32 +# else +# ifdef WIN32 +# define __WINDOWS__ WIN32 +# endif +# endif +# endif +#endif + +#ifdef __WINDOWS__ +# ifndef __CYGWIN__ +/* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory + separator when it is set. */ +# define LT_DIRSEP_CHAR '\\' +# define LT_PATHSEP_CHAR ';' +# endif +#endif +#ifndef LT_PATHSEP_CHAR +# define LT_PATHSEP_CHAR ':' +#endif + +/* DLL building support on win32 hosts; mostly to workaround their + ridiculous implementation of data symbol exporting. */ +#ifndef LT_SCOPE +# ifdef __WINDOWS__ +# ifdef DLL_EXPORT /* defined by libtool (if required) */ +# define LT_SCOPE __declspec(dllexport) +# endif +# ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */ +# define LT_SCOPE extern __declspec(dllimport) +# endif +# endif +# ifndef LT_SCOPE /* static linking or !__WINDOWS__ */ +# define LT_SCOPE extern +# endif +#endif + + + + +/* --- DYNAMIC MODULE LOADING API --- */ + + +typedef struct xmlsec_lt_dlhandle_struct *xmlsec_lt_dlhandle; /* A loaded module. */ + +/* Initialisation and finalisation functions for libltdl. */ +extern int xmlsec_lt_dlinit LT_PARAMS((void)); +extern int xmlsec_lt_dlexit LT_PARAMS((void)); + +/* Module search path manipulation. */ +extern int xmlsec_lt_dladdsearchdir LT_PARAMS((const char *search_dir)); +extern int xmlsec_lt_dlinsertsearchdir LT_PARAMS((const char *before, + const char *search_dir)); +extern int xmlsec_lt_dlsetsearchpath LT_PARAMS((const char *search_path)); +extern const char *xmlsec_lt_dlgetsearchpath LT_PARAMS((void)); +extern int xmlsec_lt_dlforeachfile LT_PARAMS(( + const char *search_path, + int (*func) (const char *filename, xmlsec_lt_ptr data), + xmlsec_lt_ptr data)); + +/* Portable libltdl versions of the system dlopen() API. */ +extern xmlsec_lt_dlhandle xmlsec_lt_dlopen LT_PARAMS((const char *filename)); +extern xmlsec_lt_dlhandle xmlsec_lt_dlopenext LT_PARAMS((const char *filename)); +extern xmlsec_lt_ptr xmlsec_lt_dlsym LT_PARAMS((xmlsec_lt_dlhandle handle, + const char *name)); +extern const char *xmlsec_lt_dlerror LT_PARAMS((void)); +extern int xmlsec_lt_dlclose LT_PARAMS((xmlsec_lt_dlhandle handle)); + +/* Module residency management. */ +extern int xmlsec_lt_dlmakeresident LT_PARAMS((xmlsec_lt_dlhandle handle)); +extern int xmlsec_lt_dlisresident LT_PARAMS((xmlsec_lt_dlhandle handle)); + + + + +/* --- MUTEX LOCKING --- */ + + +typedef void xmlsec_lt_dlmutex_lock LT_PARAMS((void)); +typedef void xmlsec_lt_dlmutex_unlock LT_PARAMS((void)); +typedef void xmlsec_lt_dlmutex_seterror LT_PARAMS((const char *errmsg)); +typedef const char *xmlsec_lt_dlmutex_geterror LT_PARAMS((void)); + +extern int xmlsec_lt_dlmutex_register LT_PARAMS((xmlsec_lt_dlmutex_lock *lock, + xmlsec_lt_dlmutex_unlock *unlock, + xmlsec_lt_dlmutex_seterror *seterror, + xmlsec_lt_dlmutex_geterror *geterror)); + + + + +/* --- MEMORY HANDLING --- */ + + +/* By default, the realloc function pointer is set to our internal + realloc implementation which iself uses xmlsec_lt_dlmalloc and xmlsec_lt_dlfree. + libltdl relies on a featureful realloc, but if you are sure yours + has the right semantics then you can assign it directly. Generally, + it is safe to assign just a malloc() and a free() function. */ +LT_SCOPE xmlsec_lt_ptr (*xmlsec_lt_dlmalloc) LT_PARAMS((size_t size)); +LT_SCOPE xmlsec_lt_ptr (*xmlsec_lt_dlrealloc) LT_PARAMS((xmlsec_lt_ptr ptr, size_t size)); +LT_SCOPE void (*xmlsec_lt_dlfree) LT_PARAMS((xmlsec_lt_ptr ptr)); + + + + +/* --- PRELOADED MODULE SUPPORT --- */ + + +/* A preopened symbol. Arrays of this type comprise the exported + symbols for a dlpreopened module. */ +typedef struct { + const char *name; + xmlsec_lt_ptr address; +} xmlsec_lt_dlsymlist; + +extern int xmlsec_lt_dlpreload LT_PARAMS((const xmlsec_lt_dlsymlist *preloaded)); +extern int xmlsec_lt_dlpreload_default + LT_PARAMS((const xmlsec_lt_dlsymlist *preloaded)); + +#define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \ + extern const xmlsec_lt_dlsymlist xmlsec_lt_preloaded_symbols[]; \ + xmlsec_lt_dlpreload_default(xmlsec_lt_preloaded_symbols); \ + }LT_STMT_END + + + + +/* --- MODULE INFORMATION --- */ + + +/* Read only information pertaining to a loaded module. */ +typedef struct { + char *filename; /* file name */ + char *name; /* module name */ + int ref_count; /* number of times xmlsec_lt_dlopened minus + number of times xmlsec_lt_dlclosed. */ +} xmlsec_lt_dlinfo; + +extern const xmlsec_lt_dlinfo *xmlsec_lt_dlgetinfo LT_PARAMS((xmlsec_lt_dlhandle handle)); +extern xmlsec_lt_dlhandle xmlsec_lt_dlhandle_next LT_PARAMS((xmlsec_lt_dlhandle place)); +extern int xmlsec_lt_dlforeach LT_PARAMS(( + int (*func) (xmlsec_lt_dlhandle handle, xmlsec_lt_ptr data), + xmlsec_lt_ptr data)); + +/* Associating user data with loaded modules. */ +typedef unsigned xmlsec_lt_dlcaller_id; + +extern xmlsec_lt_dlcaller_id xmlsec_lt_dlcaller_register LT_PARAMS((void)); +extern xmlsec_lt_ptr xmlsec_lt_dlcaller_set_data LT_PARAMS((xmlsec_lt_dlcaller_id key, + xmlsec_lt_dlhandle handle, + xmlsec_lt_ptr data)); +extern xmlsec_lt_ptr xmlsec_lt_dlcaller_get_data LT_PARAMS((xmlsec_lt_dlcaller_id key, + xmlsec_lt_dlhandle handle)); + + + +/* --- USER MODULE LOADER API --- */ + + +typedef struct xmlsec_lt_dlloader xmlsec_lt_dlloader; +typedef xmlsec_lt_ptr xmlsec_lt_user_data; +typedef xmlsec_lt_ptr xmlsec_lt_module; + +/* Function pointer types for creating user defined module loaders. */ +typedef xmlsec_lt_module xmlsec_lt_module_open LT_PARAMS((xmlsec_lt_user_data loader_data, + const char *filename)); +typedef int xmlsec_lt_module_close LT_PARAMS((xmlsec_lt_user_data loader_data, + xmlsec_lt_module handle)); +typedef xmlsec_lt_ptr xmlsec_lt_find_sym LT_PARAMS((xmlsec_lt_user_data loader_data, + xmlsec_lt_module handle, + const char *symbol)); +typedef int xmlsec_lt_dlloader_exit LT_PARAMS((xmlsec_lt_user_data loader_data)); + +struct xmlsec_lt_user_dlloader { + const char *sym_prefix; + xmlsec_lt_module_open *module_open; + xmlsec_lt_module_close *module_close; + xmlsec_lt_find_sym *find_sym; + xmlsec_lt_dlloader_exit *dlloader_exit; + xmlsec_lt_user_data dlloader_data; +}; + +extern xmlsec_lt_dlloader *xmlsec_lt_dlloader_next LT_PARAMS((xmlsec_lt_dlloader *place)); +extern xmlsec_lt_dlloader *xmlsec_lt_dlloader_find LT_PARAMS(( + const char *loader_name)); +extern const char *xmlsec_lt_dlloader_name LT_PARAMS((xmlsec_lt_dlloader *place)); +extern xmlsec_lt_user_data *xmlsec_lt_dlloader_data LT_PARAMS((xmlsec_lt_dlloader *place)); +extern int xmlsec_lt_dlloader_add LT_PARAMS((xmlsec_lt_dlloader *place, + const struct xmlsec_lt_user_dlloader *dlloader, + const char *loader_name)); +extern int xmlsec_lt_dlloader_remove LT_PARAMS(( + const char *loader_name)); + + + +/* --- ERROR MESSAGE HANDLING --- */ + + +/* Defining error strings alongside their symbolic names in a macro in + this way allows us to expand the macro in different contexts with + confidence that the enumeration of symbolic names will map correctly + onto the table of error strings. */ +#define xmlsec_lt_dlerror_table \ + LT_ERROR(UNKNOWN, "unknown error") \ + LT_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available") \ + LT_ERROR(INVALID_LOADER, "invalid loader") \ + LT_ERROR(INIT_LOADER, "loader initialization failed") \ + LT_ERROR(REMOVE_LOADER, "loader removal failed") \ + LT_ERROR(FILE_NOT_FOUND, "file not found") \ + LT_ERROR(DEPLIB_NOT_FOUND, "dependency library not found") \ + LT_ERROR(NO_SYMBOLS, "no symbols defined") \ + LT_ERROR(CANNOT_OPEN, "can't open the module") \ + LT_ERROR(CANNOT_CLOSE, "can't close the module") \ + LT_ERROR(SYMBOL_NOT_FOUND, "symbol not found") \ + LT_ERROR(NO_MEMORY, "not enough memory") \ + LT_ERROR(INVALID_HANDLE, "invalid module handle") \ + LT_ERROR(BUFFER_OVERFLOW, "internal buffer overflow") \ + LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \ + LT_ERROR(SHUTDOWN, "library already shutdown") \ + LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \ + LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration") \ + LT_ERROR(INVALID_POSITION, "invalid search path insert position") + +/* Enumerate the symbolic error names. */ +enum { +#define LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name), + xmlsec_lt_dlerror_table +#undef LT_ERROR + + LT_ERROR_MAX +}; + +/* These functions are only useful from inside custom module loaders. */ +extern int xmlsec_lt_dladderror LT_PARAMS((const char *diagnostic)); +extern int xmlsec_lt_dlseterror LT_PARAMS((int errorcode)); + + + + +/* --- SOURCE COMPATIBILITY WITH OLD LIBLTDL --- */ + + +#ifdef LT_NON_POSIX_NAMESPACE +# define xmlsec_lt_ptr_t xmlsec_lt_ptr +# define xmlsec_lt_module_t xmlsec_lt_module +# define xmlsec_lt_module_open_t xmlsec_lt_module_open +# define xmlsec_lt_module_close_t xmlsec_lt_module_close +# define xmlsec_lt_find_sym_t xmlsec_lt_find_sym +# define xmlsec_lt_dlloader_exit_t xmlsec_lt_dlloader_exit +# define xmlsec_lt_dlloader_t xmlsec_lt_dlloader +# define xmlsec_lt_dlloader_data_t xmlsec_lt_user_data +#endif + +LT_END_C_DECLS + +#endif /* !LTDL_H */ diff --git a/src/xmlsec.c b/src/xmlsec.c index c93a942d..8132c1d8 100644 --- a/src/xmlsec.c +++ b/src/xmlsec.c @@ -19,6 +19,7 @@ #include <xmlsec/xmltree.h> #include <xmlsec/keys.h> #include <xmlsec/transforms.h> +#include <xmlsec/app.h> #include <xmlsec/io.h> #include <xmlsec/xkms.h> #include <xmlsec/errors.h> @@ -36,6 +37,17 @@ xmlSecInit(void) { xmlSecErrorsInit(); xmlSecIOInit(); +#ifndef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING + if(xmlSecCryptoDLInit() < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoDLInit", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } +#endif /* XMLSEC_NO_CRYPTO_DYNAMIC_LOADING */ + if(xmlSecKeyDataIdsInit() < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, @@ -77,6 +89,7 @@ xmlSecInit(void) { */ int xmlSecShutdown(void) { + int res = 0; #ifndef XMLSEC_NO_XKMS xmlSecXkmsRespondWithIdsShutdown(); @@ -84,8 +97,20 @@ xmlSecShutdown(void) { xmlSecTransformIdsShutdown(); xmlSecKeyDataIdsShutdown(); + +#ifndef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING + if(xmlSecCryptoDLShutdown() < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecCryptoDLShutdown", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + res = -1; + } +#endif /* XMLSEC_NO_CRYPTO_DYNAMIC_LOADING */ + xmlSecIOShutdown(); xmlSecErrorsShutdown(); - return(0); + return(res); } diff --git a/tests/testDSig.sh b/tests/testDSig.sh index 47badd8b..a401b568 100755 --- a/tests/testDSig.sh +++ b/tests/testDSig.sh @@ -1,8 +1,9 @@ #!/bin/sh -topfolder=$1 -xmlsec_app=$2 -file_format=$3 +crypto=$1 +topfolder=$2 +xmlsec_app=$3 +file_format=$4 pub_key_format=$file_format cert_format=$file_format @@ -18,21 +19,26 @@ keysfile=$topfolder/keys.xml valgrind_suppression="--suppressions=$topfolder/openssl.supp --suppressions=$topfolder/nss.supp" valgrind_options="--leak-check=yes --show-reachable=yes --num-callers=32 -v" +if [ "z$crypto" != "z" -a "z$crypto" != "zdefault" ] ; then + xmlsec_params="$xmlsec_params --crypto $crypto" +fi +xmlsec_params="$xmlsec_params --crypto-config $crypto_config" + if [ -n "$DEBUG_MEMORY" ] ; then export VALGRIND="valgrind $valgrind_options" export REPEAT=3 - export EXTRA_PARAMS="--repeat $REPEAT" + xmlsec_params="$xmlsec_params --repeat $REPEAT" fi if [ -n "$PERF_TEST" ] ; then - export EXTRA_PARAMS="--repeat $PERF_TEST" + xmlsec_params="$xmlsec_params --repeat $PERF_TEST" fi printRes() { - if [ $? = 0 ]; then + if [ $1 = 0 ]; then echo " OK" else - echo " Fail ($?)" + echo " Fail" fi if [ -f .memdump ] ; then cat .memdump >> $logfile @@ -46,22 +52,22 @@ execDSigTest() { rm -f $tmpfile printf " Verify existing signature " - echo "$xmlsec_app verify --crypto-config $crypto_config $2 $file.xml" >> $logfile - $VALGRIND $xmlsec_app verify --crypto-config $crypto_config $EXTRA_PARAMS $2 $file.xml >> $logfile 2>> $logfile - printRes + echo "$xmlsec_app verify $xmlsec_params $2 $file.xml" >> $logfile + $VALGRIND $xmlsec_app verify $xmlsec_params $2 $file.xml >> $logfile 2>> $logfile + printRes $? if [ -n "$3" -a -z "$PERF_TEST" ] ; then printf " Create new signature " - echo "$xmlsec_app sign --crypto-config $crypto_config $3 --output $tmpfile $file.tmpl" >> $logfile - $VALGRIND $xmlsec_app sign --crypto-config $crypto_config --output $tmpfile $EXTRA_PARAMS $3 $file.tmpl >> $logfile 2>> $logfile - printRes + echo "$xmlsec_app sign $xmlsec_params $3 --output $tmpfile $file.tmpl" >> $logfile + $VALGRIND $xmlsec_app sign $xmlsec_params $3 --output $tmpfile $file.tmpl >> $logfile 2>> $logfile + printRes $? if [ -n "$4" ] ; then if [ -z "$VALGRIND" ] ; then printf " Verify new signature " - echo "$xmlsec_app verify --crypto-config $crypto_config $4 $tmpfile" >> $logfile - $VALGRIND $xmlsec_app verify --crypto-config $crypto_config $EXTRA_PARAMS $4 $tmpfile >> $logfile 2>> $logfile - printRes + echo "$xmlsec_app verify $xmlsec_params $4 $tmpfile" >> $logfile + $VALGRIND $xmlsec_app verify $xmlsec_params $4 $tmpfile >> $logfile 2>> $logfile + printRes $? fi fi fi @@ -219,14 +225,13 @@ execDSigTest "merlin-xpath-filter2-three/sign-spec" \ # test dynamic signature echo "Dynamic signature template" printf " Create new signature " -echo "$xmlsec_app sign-tmpl --crypto-config $crypto_config --keys-file $topfolder/keys.xml --output $tmpfile" >> $logfile -$VALGRIND $xmlsec_app sign-tmpl --crypto-config $crypto_config $EXTRA_PARAMS --keys-file $topfolder/keys.xml --output $tmpfile >> $logfile 2>> $logfile -printRes +echo "$xmlsec_app sign-tmpl $xmlsec_params --keys-file $topfolder/keys.xml --output $tmpfile" >> $logfile +$VALGRIND $xmlsec_app sign-tmpl $xmlsec_params --keys-file $topfolder/keys.xml --output $tmpfile >> $logfile 2>> $logfile +printRes $? printf " Verify new signature " -echo "$xmlsec_app verify --crypto-config $crypto_config --keys-file $topfolder/keys.xml $tmpfile" >> $logfile -$VALGRIND $xmlsec_app verify --crypto-config $crypto_config $EXTRA_PARAMS --keys-file $topfolder/keys.xml $tmpfile >> $logfile 2>> $logfile -printRes - +echo "$xmlsec_app verify --keys-file $topfolder/keys.xml $tmpfile" >> $logfile +$VALGRIND $xmlsec_app verify $xmlsec_params --keys-file $topfolder/keys.xml $tmpfile >> $logfile 2>> $logfile +printRes $? echo "--------- Negative Testing: next test MUST FAIL ----------" execDSigTest "merlin-xmldsig-twenty-three/signature-x509-crt-crl" \ diff --git a/tests/testEnc.sh b/tests/testEnc.sh index 55674000..ce2af814 100755 --- a/tests/testEnc.sh +++ b/tests/testEnc.sh @@ -1,8 +1,9 @@ #!/bin/sh -topfolder=$1 -xmlsec_app=$2 -file_format=$3 +crypto=$1 +topfolder=$2 +xmlsec_app=$3 +file_format=$4 pub_key_format=$file_format cert_format=$file_format @@ -18,18 +19,24 @@ keysfile=$topfolder/keys.xml valgrind_suppression="--suppressions=$topfolder/openssl.supp --suppressions=$topfolder/nss.supp" valgrind_options="--leak-check=yes --show-reachable=yes --num-callers=32 -v" + +if [ "z$crypto" != "z" -a "z$crypto" != "zdefault" ] ; then + xmlsec_params="$xmlsec_params --crypto $crypto" +fi +xmlsec_params="$xmlsec_params --crypto-config $crypto_config" + if [ -n "$DEBUG_MEMORY" ] ; then export VALGRIND="valgrind $valgrind_options" export REPEAT=3 - export EXTRA_PARAMS="--repeat $REPEAT" + xmlsec_params="$xmlsec_params --repeat $REPEAT" fi if [ -n "$PERF_TEST" ] ; then - export EXTRA_PARAMS="--repeat $PERF_TEST" + export xmlsec_params="$xmlsec_params --repeat $PERF_TEST" fi printRes() { - if [ $? = 0 ]; then + if [ $1 = 0 ]; then echo " OK" else echo " Fail" @@ -47,11 +54,11 @@ execEncTest() { printf " Decrypt existing document " rm -f $tmpfile - echo "$xmlsec_app decrypt --crypto-config $crypto_config $2 $file.xml" >> $logfile - $VALGRIND $xmlsec_app decrypt --crypto-config $crypto_config $EXTRA_PARAMS $2 $file.xml > $tmpfile 2>> $logfile + echo "$xmlsec_app decrypt $xmlsec_params $2 $file.xml" >> $logfile + $VALGRIND $xmlsec_app decrypt xmlsec_params $2 $file.xml > $tmpfile 2>> $logfile if [ $? = 0 ]; then diff $file.data $tmpfile >> $logfile 2>> $logfile - printRes + printRes $? else echo " Error" fi @@ -59,18 +66,18 @@ execEncTest() { if [ -n "$3" -a -z "$PERF_TEST" ] ; then printf " Encrypt document " rm -f $tmpfile - echo "$xmlsec_app encrypt --crypto-config $crypto_config $3 $file.tmpl" >> $logfile - $VALGRIND $xmlsec_app encrypt --crypto-config $crypto_config --output $tmpfile $EXTRA_PARAMS $3 $file.tmpl >> $logfile 2>> $logfile - printRes + echo "$xmlsec_app encrypt $xmlsec_params $3 --output $tmpfile $file.tmpl" >> $logfile + $VALGRIND $xmlsec_app encrypt $xmlsec_params $3 --output $tmpfile $file.tmpl >> $logfile 2>> $logfile + printRes $? if [ -n "$4" ] ; then if [ -z "$VALGRIND" ] ; then printf " Decrypt new document " - echo "$xmlsec_app decrypt --crypto-config $crypto_config $4 $tmpfile" >> $logfile - $VALGRIND $xmlsec_app decrypt --crypto-config $crypto_config --output $tmpfile.2 $EXTRA_PARAMS $4 $tmpfile >> $logfile 2>> $logfile + echo "$xmlsec_app decrypt $xmlsec_params $4 --output $tmpfile.2 $tmpfile" >> $logfile + $VALGRIND $xmlsec_app decrypt $xmlsec_params $4 --output $tmpfile.2 $tmpfile >> $logfile 2>> $logfile if [ $? = 0 ]; then diff $file.data $tmpfile.2 >> $logfile 2>> $logfile - printRes + printRes $? else echo " Error" fi @@ -296,13 +303,14 @@ execEncTest "01-phaos-xmlenc-3/enc-text-aes128-kw-aes192" \ # test dynamic encryption echo "Dynamic encryption template" printf " Encrypt template " -echo "$xmlsec_app encrypt-tmpl --crypto-config $crypto_config --keys-file $topfolder/keys.xml --output $tmpfile" >> $logfile -$VALGRIND $xmlsec_app encrypt-tmpl --crypto-config $crypto_config $EXTRA_PARAMS --keys-file $topfolder/keys.xml --output $tmpfile >> $logfile 2>> $logfile -printRes +echo "$xmlsec_app encrypt-tmpl $xmlsec_params --keys-file $topfolder/keys.xml --output $tmpfile" >> $logfile +$VALGRIND $xmlsec_app encrypt-tmpl $xmlsec_params --keys-file $topfolder/keys.xml --output $tmpfile >> $logfile 2>> $logfile +printRes $? printf " Decrypt document " -echo "$xmlsec_app decrypt --crypto-config $crypto_config --keys-file $topfolder/keys.xml $tmpfile" >> $logfile -$VALGRIND $xmlsec_app decrypt --crypto-config $crypto_config $EXTRA_PARAMS --keys-file $topfolder/keys.xml $tmpfile >> $logfile 2>> $logfile -printRes +echo "$xmlsec_app decrypt $xmlsec_params $topfolder/keys.xml $tmpfile" >> $logfile +$VALGRIND $xmlsec_app decrypt $xmlsec_params --keys-file $topfolder/keys.xml $tmpfile >> $logfile 2>> $logfile +printRes $? + echo "--------- Negative Testing: Following tests MUST FAIL ----------" diff --git a/tests/testKeys.sh b/tests/testKeys.sh index c5ffc1df..6c8cd097 100755 --- a/tests/testKeys.sh +++ b/tests/testKeys.sh @@ -1,8 +1,9 @@ #!/bin/sh -topfolder=$1 -xmlsec_app=$2 -file_format=$3 +crypto=$1 +topfolder=$2 +xmlsec_app=$3 +file_format=$4 pub_key_format=$file_format cert_format=$file_format @@ -16,8 +17,13 @@ logfile=/tmp/testKeys.$timestamp-$$.log script="$0" keysfile=$topfolder/keys.xml -printRes() { - if [ $? = 0 ]; then +if [ "z$crypto" != "z" -a "z$crypto" != "zdefault" ] ; then + xmlsec_params="$xmlsec_params --crypto $crypto" +fi +xmlsec_params="$xmlsec_params --crypto-config $crypto_config" + +printRes() { + if [ $1 = 0 ]; then echo " OK" else echo " Fail" @@ -31,7 +37,7 @@ echo "--- testKeys started ($timestamp) ---" echo "--- testKeys started ($timestamp) ---" >> $logfile printf " Creating new keys " -$xmlsec_app keys --crypto-config $crypto_config \ +$xmlsec_app keys $xmlsec_params \ --gen-key:test-hmac-sha1 hmac-192 \ --gen-key:test-rsa rsa-1024 \ --gen-key:test-dsa dsa-1024 \ @@ -40,7 +46,7 @@ $xmlsec_app keys --crypto-config $crypto_config \ --gen-key:test-aes192 aes-192 \ --gen-key:test-aes256 aes-256 \ $keysfile >> $logfile 2>> $logfile -printRes +printRes $? rm -rf $tmpfile diff --git a/win32/Makefile.msvc b/win32/Makefile.msvc index b192978c..82d74c0c 100644 --- a/win32/Makefile.msvc +++ b/win32/Makefile.msvc @@ -32,6 +32,11 @@ AUTOCONF = .\configure.txt #WITH_XMLSEC_DEBUG = 1 #DEBUG = 0 #WITH_CRYPTO=openssl +#WITH_CRYPTO=openssl +#WITH_DEFAULT_CRYPTO=openssl +#WITH_OPENSSL=1 +#WITH_OPENSSL_096=0 +#WITH_NSS=0 #WITH_LIBXSLT=1 #STATIC = 0 #PREFIX = . # set this to the right value. @@ -71,6 +76,7 @@ XMLSEC_OBJS = \ $(XMLSEC_INTDIR)\base64.obj\ $(XMLSEC_INTDIR)\buffer.obj \ $(XMLSEC_INTDIR)\c14n.obj \ + $(XMLSEC_INTDIR)\dl.obj \ $(XMLSEC_INTDIR)\enveloped.obj \ $(XMLSEC_INTDIR)\errors.obj \ $(XMLSEC_INTDIR)\io.obj \ @@ -99,6 +105,7 @@ XMLSEC_OBJS_A = \ $(XMLSEC_INTDIR_A)\base64.obj\ $(XMLSEC_INTDIR_A)\buffer.obj \ $(XMLSEC_INTDIR_A)\c14n.obj \ + $(XMLSEC_INTDIR_A)\dl.obj \ $(XMLSEC_INTDIR_A)\enveloped.obj \ $(XMLSEC_INTDIR_A)\errors.obj \ $(XMLSEC_INTDIR_A)\io.obj \ @@ -197,60 +204,79 @@ XMLSEC_NSS_OBJS_A = \ $(XMLSEC_NSS_INTDIR_A)\kw_aes.obj\ $(XMLSEC_NSS_INTDIR_A)\strings.obj +# source folders +XMLSEC_OPENSSL_SRCDIR = $(XMLSEC_SRCDIR)\openssl +XMLSEC_NSS_SRCDIR = $(XMLSEC_SRCDIR)\nss + +# compilation cflags +!if "$(WITH_OPENSSL_096)" == "1" +XMLSEC_OPENSSL_CFLAGS = /D "XMLSEC_OPENSSL_096" /D "XMLSEC_CRYPTO_OPENSSL" /D "XMLSEC_CRYPTO=\"openssl\"" +!else +XMLSEC_OPENSSL_CFLAGS = /D "XMLSEC_CRYPTO_OPENSSL" /D "XMLSEC_CRYPTO=\"openssl\"" +!endif +XMLSEC_NSS_CFLAGS = /D "XMLSEC_CRYPTO_NSS" /D "XMLSEC_CRYPTO=\"nss\"" + +# libs +XMLSEC_OPENSSL_SOLIBS = libeay32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib +XMLSEC_OPENSSL_ALIBS = libeay32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib +XMLSEC_NSS_SOLIBS = smime3.lib ssl3.lib nss3.lib libnspr4.lib libplds4.lib libplc4.lib kernel32.lib user32.lib gdi32.lib +XMLSEC_NSS_ALIBS = smime3.lib ssl3.lib nss3.lib libnspr4_s.lib libplds4_s.lib libplc4_s.lib kernel32.lib user32.lib gdi32.lib + +# Names of various input and output components. +XMLSEC_NAME = xmlsec +XMLSEC_BASENAME = lib$(XMLSEC_NAME) +XMLSEC_SO = $(XMLSEC_BASENAME).dll +XMLSEC_IMP = $(XMLSEC_BASENAME).lib +XMLSEC_A = $(XMLSEC_BASENAME)_a.lib + +XMLSEC_OPENSSL_NAME = $(XMLSEC_NAME)-openssl +XMLSEC_OPENSSL_BASENAME = lib$(XMLSEC_OPENSSL_NAME) +XMLSEC_OPENSSL_SO = $(XMLSEC_OPENSSL_BASENAME).dll +XMLSEC_OPENSSL_IMP = $(XMLSEC_OPENSSL_BASENAME).lib +XMLSEC_OPENSSL_A = $(XMLSEC_OPENSSL_BASENAME)_a.lib + +XMLSEC_NSS_NAME = $(XMLSEC_NAME)-nss +XMLSEC_NSS_BASENAME = lib$(XMLSEC_NSS_NAME) +XMLSEC_NSS_SO = $(XMLSEC_NSS_BASENAME).dll +XMLSEC_NSS_IMP = $(XMLSEC_NSS_BASENAME).lib +XMLSEC_NSS_A = $(XMLSEC_NSS_BASENAME)_a.lib + # configurable options !if "$(WITH_LIBXSLT)" == "1" !else CFLAGS = $(CFLAGS) /DXMLSEC_NO_XSLT=1 !endif -!if "$(WITH_CRYPTO)" == "openssl" -XMLSEC_CRYPTO = "openssl" -XMLSEC_CRYPTO_OBJS = $(XMLSEC_OPENSSL_OBJS) -XMLSEC_CRYPTO_OBJS_A = $(XMLSEC_OPENSSL_OBJS_A) -XMLSEC_CRYPTO_INTDIR = $(XMLSEC_OPENSSL_INTDIR) -XMLSEC_CRYPTO_INTDIR_A = $(XMLSEC_OPENSSL_INTDIR_A) -XMLSEC_CRYPTO_SRCDIR = $(XMLSEC_SRCDIR)\openssl -XMLSEC_CRYPTO_CFLAGS = /D "XMLSEC_CRYPTO_OPENSSL" /D "XMLSEC_CRYPTO=\"openssl\"" -XMLSEC_CRYPTO_SOLIBS = libeay32.lib wsock32.lib user32.lib gdi32.lib -XMLSEC_CRYPTO_ALIBS = libeay32.lib wsock32.lib user32.lib gdi32.lib +!if "$(WITH_DEFAULT_CRYPTO)" == "openssl" +XMLSEC_CRYPTO = "openssl" +XMLSEC_CRYPTO_CFLAGS = $(XMLSEC_OPENSSL_CFLAGS) +XMLSEC_CRYPTO_SOLIBS = $(XMLSEC_OPENSSL_SOLIBS) +XMLSEC_CRYPTO_ALIBS = $(XMLSEC_OPENSSL_ALIBS) +XMLSEC_CRYPTO_SO = $(XMLSEC_OPENSSL_SO) +XMLSEC_CRYPTO_IMP = $(XMLSEC_OPENSSL_IMP) +XMLSEC_CRYPTO_A = $(XMLSEC_OPENSSL_A) !endif -!if "$(WITH_CRYPTO)" == "openssl_096" -XMLSEC_CRYPTO = "openssl" -XMLSEC_CRYPTO_OBJS = $(XMLSEC_OPENSSL_OBJS) -XMLSEC_CRYPTO_OBJS_A = $(XMLSEC_OPENSSL_OBJS_A) -XMLSEC_CRYPTO_INTDIR = $(XMLSEC_OPENSSL_INTDIR) -XMLSEC_CRYPTO_INTDIR_A = $(XMLSEC_OPENSSL_INTDIR_A) -XMLSEC_CRYPTO_SRCDIR = $(XMLSEC_SRCDIR)\openssl -XMLSEC_CRYPTO_CFLAGS = /D "XMLSEC_OPENSSL_096" /D "XMLSEC_CRYPTO_OPENSSL" /D "XMLSEC_CRYPTO=\"openssl\"" -XMLSEC_CRYPTO_SOLIBS = libeay32.lib wsock32.lib user32.lib gdi32.lib -XMLSEC_CRYPTO_ALIBS = libeay32_a.lib wsock32.lib user32.lib gdi32.lib +!if "$(WITH_DEFAULT_CRYPTO)" == "openssl_096" +XMLSEC_CRYPTO = "openssl" +XMLSEC_CRYPTO_CFLAGS = $(XMLSEC_OPENSSL_CFLAGS) +XMLSEC_CRYPTO_SOLIBS = $(XMLSEC_OPENSSL_SOLIBS) +XMLSEC_CRYPTO_ALIBS = $(XMLSEC_OPENSSL_ALIBS) +XMLSEC_CRYPTO_SO = $(XMLSEC_OPENSSL_SO) +XMLSEC_CRYPTO_IMP = $(XMLSEC_OPENSSL_IMP) +XMLSEC_CRYPTO_A = $(XMLSEC_OPENSSL_A) !endif -!if "$(WITH_CRYPTO)" == "nss" -XMLSEC_CRYPTO = "nss" -XMLSEC_CRYPTO_OBJS = $(XMLSEC_NSS_OBJS) -XMLSEC_CRYPTO_OBJS_A = $(XMLSEC_NSS_OBJS_A) -XMLSEC_CRYPTO_INTDIR = $(XMLSEC_NSS_INTDIR) -XMLSEC_CRYPTO_INTDIR_A = $(XMLSEC_NSS_INTDIR_A) -XMLSEC_CRYPTO_SRCDIR = $(XMLSEC_SRCDIR)\nss -XMLSEC_CRYPTO_CFLAGS = /D "XMLSEC_CRYPTO_NSS" /D "XMLSEC_CRYPTO=\"nss\"" -XMLSEC_CRYPTO_SOLIBS = smime3.lib ssl3.lib nss3.lib libnspr4.lib libplds4.lib libplc4.lib -XMLSEC_CRYPTO_ALIBS = smime3.lib ssl3.lib nss3.lib libnspr4_s.lib libplds4_s.lib libplc4_s.lib +!if "$(WITH_DEFAULT_CRYPTO)" == "nss" +XMLSEC_CRYPTO = "nss" +XMLSEC_CRYPTO_CFLAGS = $(XMLSEC_NSS_CFLAGS) +XMLSEC_CRYPTO_SOLIBS = $(XMLSEC_NSS_SOLIBS) +XMLSEC_CRYPTO_ALIBS = $(XMLSEC_NSS_ALIBS) +XMLSEC_CRYPTO_SO = $(XMLSEC_NSS_SO) +XMLSEC_CRYPTO_IMP = $(XMLSEC_NSS_IMP) +XMLSEC_CRYPTO_A = $(XMLSEC_NSS_A) !endif -# Names of various input and output components. -XMLSEC_NAME = xmlsec -XMLSEC_BASENAME = lib$(XMLSEC_NAME) -XMLSEC_SO = $(XMLSEC_BASENAME).dll -XMLSEC_IMP = $(XMLSEC_BASENAME).lib -XMLSEC_A = $(XMLSEC_BASENAME)_a.lib - -XMLSEC_CRYPTO_NAME = xmlsec-$(XMLSEC_CRYPTO) -XMLSEC_CRYPTO_BASENAME = lib$(XMLSEC_CRYPTO_NAME) -XMLSEC_CRYPTO_SO = $(XMLSEC_CRYPTO_BASENAME).dll -XMLSEC_CRYPTO_IMP = $(XMLSEC_CRYPTO_BASENAME).lib -XMLSEC_CRYPTO_A = $(XMLSEC_CRYPTO_BASENAME)_a.lib # The preprocessor and its options. CPP = cl.exe /EP @@ -258,9 +284,10 @@ CPPFLAGS = /nologo # The compiler and its options. CC = cl.exe -CFLAGS = /nologo /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_REENTRANT" /W1 /MD $(XMLSEC_CRYPTO_CFLAGS) -CFLAGS = $(CFLAGS) /I$(BASEDIR) /I$(BASEDIR)\include /I$(XMLSEC_SRCDIR) +CFLAGS = /nologo /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_REENTRANT" /W1 /MD +CFLAGS = $(CFLAGS) /I$(BASEDIR) /I$(BASEDIR)\include CFLAGS = $(CFLAGS) /I$(INCPREFIX) +CFLAGS = $(CFLAGS) /D PACKAGE="$(XMLSEC_NAME)" /D "XMLSEC_NO_CRYPTO_DYNAMIC_LOADING" # The linker and its options. LD = link.exe @@ -281,8 +308,6 @@ CFLAGS = $(CFLAGS) /D "NDEBUG" /O2 LDFLAGS = $(LDFLAGS) /OPT:NOWIN98 !endif - - SOLIBS = $(LIBS) libxml2.lib ALIBS = $(LIBS) libxml2_a.lib !if "$(WITH_ICONV)" == "1" @@ -296,26 +321,45 @@ ALIBS = $(ALIBS) libxslt_a.lib # XmlSec and friends executables. !if "$(STATIC)" == "1" -APPS = $(BINDIR)\xmlseca.exe -APPLIBS = $(ALIBS) $(XMLSEC_CRYPTO_ALIBS) +APP_NAME = xmlseca.exe +APPLIBS = $(ALIBS) $(XMLSEC_CRYPTO_ALIBS) !else -APPS = $(BINDIR)\xmlsec.exe -APPLIBS = $(SOLIBS) $(XMLSEC_CRYPTO_SOLIBS) +APP_NAME = xmlsec.exe +APPLIBS = $(SOLIBS) $(XMLSEC_CRYPTO_SOLIBS) !endif -all : xmlsec xmlseca apps +all : xmlsec xmlseca $(WITH_CRYPTO) apps + +xmlsec : $(XMLSEC_APPS_INTDIR) $(BINDIR)\$(XMLSEC_SO) $(WITH_DEFAULT_CRYPTO) + +xmlseca : $(XMLSEC_APPS_INTDIR_A) $(BINDIR)\$(XMLSEC_A) $(WITH_DEFAULT_CRYPTO) -xmlsec : $(XMLSEC_APPS_INTDIR) $(BINDIR)\$(XMLSEC_SO) $(BINDIR)\$(XMLSEC_CRYPTO_SO) +openssl: $(BINDIR)\$(XMLSEC_OPENSSL_SO) $(BINDIR)\$(XMLSEC_OPENSSL_A) -xmlseca : $(XMLSEC_APPS_INTDIR_A) $(BINDIR)\$(XMLSEC_A) $(BINDIR)\$(XMLSEC_CRYPTO_A) +openssl_096: $(BINDIR)\$(XMLSEC_OPENSSL_SO) $(BINDIR)\$(XMLSEC_OPENSSL_A) -apps : $(APPS) +nss: $(BINDIR)\$(XMLSEC_NSS_SO) $(BINDIR)\$(XMLSEC_NSS_A) + +apps : $(BINDIR)\$(APP_NAME) + +check : check-keys check-dsig check-enc + +check-keys : $(BINDIR)\$(APP_NAME) + sh ../tests/testKeys.sh default ../tests $(BINDIR)/$(APP_NAME) der + +check-dsig : $(BINDIR)\$(APP_NAME) + sh ../tests/testDSig.sh default ../tests $(BINDIR)/$(APP_NAME) der + +check-enc : $(BINDIR)\$(APP_NAME) + sh ../tests/testEnc.sh default ../tests $(BINDIR)/$(APP_NAME) der clean : if exist $(XMLSEC_INTDIR) rmdir /S /Q $(XMLSEC_INTDIR) if exist $(XMLSEC_INTDIR_A) rmdir /S /Q $(XMLSEC_INTDIR_A) - if exist $(XMLSEC_CRYPTO_INTDIR) rmdir /S /Q $(XMLSEC_CRYPTO_INTDIR) - if exist $(XMLSEC_CRYPTO_INTDIR_A) rmdir /S /Q $(XMLSEC_CRYPTO_INTDIR_A) + if exist $(XMLSEC_OPENSSL_INTDIR) rmdir /S /Q $(XMLSEC_OPENSSL_INTDIR) + if exist $(XMLSEC_OPENSSL_INTDIR_A) rmdir /S /Q $(XMLSEC_OPENSSL_INTDIR_A) + if exist $(XMLSEC_NSS_INTDIR) rmdir /S /Q $(XMLSEC_NSS_INTDIR) + if exist $(XMLSEC_NSS_INTDIR_A) rmdir /S /Q $(XMLSEC_NSS_INTDIR_A) if exist $(XMLSEC_APPS_INTDIR) rmdir /S /Q $(XMLSEC_APPS_INTDIR) if exist $(XMLSEC_APPS_INTDIR_A) rmdir /S /Q $(XMLSEC_APPS_INTDIR_A) if exist $(BINDIR) rmdir /S /Q $(BINDIR) @@ -324,18 +368,36 @@ rebuild : clean all install : all if not exist $(INCPREFIX)\$(XMLSEC_NAME) mkdir $(INCPREFIX)\$(XMLSEC_NAME) - if not exist $(INCPREFIX)\$(XMLSEC_NAME)\$(XMLSEC_CRYPTO) mkdir $(INCPREFIX)\$(XMLSEC_NAME)\$(XMLSEC_CRYPTO) + if exist $(BINDIR)\$(XMLSEC_OPENSSL_SO) if not exist $(INCPREFIX)\$(XMLSEC_NAME)\openssl mkdir $(INCPREFIX)\$(XMLSEC_NAME)\openssl + if exist $(BINDIR)\$(XMLSEC_NSS_SO) if not exist $(INCPREFIX)\$(XMLSEC_NAME)\nss mkdir $(INCPREFIX)\$(XMLSEC_NAME)\nss if not exist $(BINPREFIX) mkdir $(BINPREFIX) if not exist $(LIBPREFIX) mkdir $(LIBPREFIX) copy $(BASEDIR)\include\$(XMLSEC_NAME)\*.h $(INCPREFIX)\$(XMLSEC_NAME) - copy $(BASEDIR)\include\$(XMLSEC_NAME)\$(XMLSEC_CRYPTO)\*.h $(INCPREFIX)\$(XMLSEC_NAME)\$(XMLSEC_CRYPTO) + if exist $(BINDIR)\$(XMLSEC_OPENSSL_SO) copy $(BASEDIR)\include\$(XMLSEC_NAME)\openssl\*.h $(INCPREFIX)\$(XMLSEC_NAME)\openssl + if exist $(BINDIR)\$(XMLSEC_NSS_SO) copy $(BASEDIR)\include\$(XMLSEC_NAME)\nss\*.h $(INCPREFIX)\$(XMLSEC_NAME)\nss copy $(BINDIR)\$(XMLSEC_SO) $(SOPREFIX) copy $(BINDIR)\$(XMLSEC_A) $(LIBPREFIX) copy $(BINDIR)\$(XMLSEC_IMP) $(LIBPREFIX) - copy $(BINDIR)\$(XMLSEC_CRYPTO_SO) $(SOPREFIX) - copy $(BINDIR)\$(XMLSEC_CRYPTO_A) $(LIBPREFIX) - copy $(BINDIR)\$(XMLSEC_CRYPTO_IMP) $(LIBPREFIX) - copy $(BINDIR)\*.exe $(BINPREFIX) + if exist $(BINDIR)\$(XMLSEC_OPENSSL_SO) copy $(BINDIR)\$(XMLSEC_OPENSSL_SO) $(SOPREFIX) + if exist $(BINDIR)\$(XMLSEC_OPENSSL_A) copy $(BINDIR)\$(XMLSEC_OPENSSL_A) $(LIBPREFIX) + if exist $(BINDIR)\$(XMLSEC_OPENSSL_IMP) copy $(BINDIR)\$(XMLSEC_OPENSSL_IMP) $(LIBPREFIX) + if exist $(BINDIR)\$(XMLSEC_NSS_SO) copy $(BINDIR)\$(XMLSEC_NSS_SO) $(SOPREFIX) + if exist $(BINDIR)\$(XMLSEC_NSS_A) copy $(BINDIR)\$(XMLSEC_NSS_A) $(LIBPREFIX) + if exist $(BINDIR)\$(XMLSEC_NSS_IMP) copy $(BINDIR)\$(XMLSEC_NSS_IMP) $(LIBPREFIX) + copy $(BINDIR)\$(APP_NAME) $(BINPREFIX) + +uninstall : + if exist $(INCPREFIX)\$(XMLSEC_NAME) rmdir /S /Q $(INCPREFIX)\$(XMLSEC_NAME) + if exist $(SOPREFIX)\$(XMLSEC_SO) del /F /S /Q $(SOPREFIX)\$(XMLSEC_SO) + if exist $(LIBPREFIX)\$(XMLSEC_A) del /F /S /Q $(LIBPREFIX)\$(XMLSEC_A) + if exist $(LIBPREFIX)\$(XMLSEC_IMP) del /F /S /Q $(LIBPREFIX)\$(XMLSEC_IMP) + if exist $(SOPREFIX)\$(XMLSEC_OPENSSL_SO) del /F /S /Q $(SOPREFIX)\$(XMLSEC_OPENSSL_SO) + if exist $(LIBPREFIX)\$(XMLSEC_OPENSSL_A) del /F /S /Q $(LIBPREFIX)\$(XMLSEC_OPENSSL_A) + if exist $(LIBPREFIX)\$(XMLSEC_OPENSSL_IMP) del /F /S /Q $(LIBPREFIX)\$(XMLSEC_OPENSSL_IMP) + if exist $(SOPREFIX)\$(XMLSEC_NSS_SO) del /F /S /Q $(SOPREFIX)\$(XMLSEC_NSS_SO) + if exist $(LIBPREFIX)\$(XMLSEC_NSS_A) del /F /S /Q $(LIBPREFIX)\$(XMLSEC_NSS_A) + if exist $(LIBPREFIX)\$(XMLSEC_NSS_IMP) del /F /S /Q $(LIBPREFIX)\$(XMLSEC_NSS_IMP) + if exist $(BINPREFIX)\$(APP_NAME) del /F /S /Q $(BINPREFIX)\$(APP_NAME) # This is a target for me, to make a binary distribution. Not for the public use, # keep your hands off :-) @@ -358,37 +420,48 @@ $(XMLSEC_INTDIR) : $(XMLSEC_INTDIR_A) : if not exist $(XMLSEC_INTDIR_A) mkdir $(XMLSEC_INTDIR_A) -# Makes the xmlsec-crypto intermediate directory. -$(XMLSEC_CRYPTO_INTDIR) : - if not exist $(XMLSEC_CRYPTO_INTDIR) mkdir $(XMLSEC_CRYPTO_INTDIR) - -# Makes the static xmlsec-crypto intermediate directory. -$(XMLSEC_CRYPTO_INTDIR_A) : - if not exist $(XMLSEC_CRYPTO_INTDIR_A) mkdir $(XMLSEC_CRYPTO_INTDIR_A) +# Makes the xmlsec-crypto intermediate directories +$(XMLSEC_OPENSSL_INTDIR) : + if not exist $(XMLSEC_OPENSSL_INTDIR) mkdir $(XMLSEC_OPENSSL_INTDIR) +$(XMLSEC_OPENSSL_INTDIR_A) : + if not exist $(XMLSEC_OPENSSL_INTDIR_A) mkdir $(XMLSEC_OPENSSL_INTDIR_A) +$(XMLSEC_NSS_INTDIR) : + if not exist $(XMLSEC_NSS_INTDIR) mkdir $(XMLSEC_NSS_INTDIR) +$(XMLSEC_NSS_INTDIR_A) : + if not exist $(XMLSEC_NSS_INTDIR_A) mkdir $(XMLSEC_NSS_INTDIR_A) # An implicit rule for xmlsec compilation. {$(APPS_SRCDIR)}.c{$(XMLSEC_APPS_INTDIR)}.obj:: - $(CC) $(CFLAGS) /Fo$(XMLSEC_APPS_INTDIR)\ /c $< + $(CC) $(CFLAGS) $(XMLSEC_CRYPTO_CFLAGS) /Fo$(XMLSEC_APPS_INTDIR)\ /c $< {$(XMLSEC_SRCDIR)}.c{$(XMLSEC_INTDIR)}.obj:: $(CC) $(CFLAGS) /Fo$(XMLSEC_INTDIR)\ /c $< -{$(XMLSEC_SRCDIR)}.c{$(XMLSEC_CRYPTO_INTDIR)}.obj:: - $(CC) $(CFLAGS) /Fo$(XMLSEC_CRYPTO_INTDIR)\ /c $< -{$(XMLSEC_CRYPTO_SRCDIR)}.c{$(XMLSEC_CRYPTO_INTDIR)}.obj:: - $(CC) $(CFLAGS) /Fo$(XMLSEC_CRYPTO_INTDIR)\ /c $< - +{$(XMLSEC_SRCDIR)}.c{$(XMLSEC_OPENSSL_INTDIR)}.obj:: + $(CC) $(CFLAGS) /Fo$(XMLSEC_OPENSSL_INTDIR)\ /c $< +{$(XMLSEC_OPENSSL_SRCDIR)}.c{$(XMLSEC_OPENSSL_INTDIR)}.obj:: + $(CC) $(CFLAGS) $(XMLSEC_OPENSSL_CFLAGS) /Fo$(XMLSEC_OPENSSL_INTDIR)\ /c $< +{$(XMLSEC_SRCDIR)}.c{$(XMLSEC_NSS_INTDIR)}.obj:: + $(CC) $(CFLAGS) $(XMLSEC_NSS_CFLAGS) /Fo$(XMLSEC_NSS_INTDIR)\ /c $< +{$(XMLSEC_NSS_SRCDIR)}.c{$(XMLSEC_NSS_INTDIR)}.obj:: + $(CC) $(CFLAGS) $(XMLSEC_NSS_CFLAGS) /Fo$(XMLSEC_NSS_INTDIR)\ /c $< # An implicit rule for static xmlsec compilation. {$(APPS_SRCDIR)}.c{$(XMLSEC_APPS_INTDIR_A)}.obj:: $(CC) /D "LIBXML_STATIC" /D "LIBXSLT_STATIC" /D "XMLSEC_STATIC" \ - $(CFLAGS) /Fo$(XMLSEC_APPS_INTDIR_A)\ /c $< + $(CFLAGS) $(XMLSEC_CRYPTO_CFLAGS) /Fo$(XMLSEC_APPS_INTDIR_A)\ /c $< {$(XMLSEC_SRCDIR)}.c{$(XMLSEC_INTDIR_A)}.obj:: $(CC) /D "LIBXML_STATIC" /D "LIBXSLT_STATIC" /D "XMLSEC_STATIC" \ - $(CFLAGS) /Fo$(XMLSEC_INTDIR_A)\ /c $< -{$(XMLSEC_SRCDIR)}.c{$(XMLSEC_CRYPTO_INTDIR_A)}.obj:: + $(CFLAGS) $(XMLSEC_OPENSSL_CFLAGS) $(XMLSEC_CRYPTO_CFLAGS) /Fo$(XMLSEC_INTDIR_A)\ /c $< +{$(XMLSEC_SRCDIR)}.c{$(XMLSEC_OPENSSL_INTDIR_A)}.obj:: $(CC) /D "LIBXML_STATIC" /D "LIBXSLT_STATIC" /D "XMLSEC_STATIC" \ - $(CFLAGS) /Fo$(XMLSEC_CRYPTO_INTDIR_A)\ /c $< -{$(XMLSEC_CRYPTO_SRCDIR)}.c{$(XMLSEC_CRYPTO_INTDIR_A)}.obj:: + $(CFLAGS) $(XMLSEC_OPENSSL_CFLAGS) /Fo$(XMLSEC_OPENSSL_INTDIR_A)\ /c $< +{$(XMLSEC_OPENSSL_SRCDIR)}.c{$(XMLSEC_OPENSSL_INTDIR_A)}.obj:: $(CC) /D "LIBXML_STATIC" /D "LIBXSLT_STATIC" /D "XMLSEC_STATIC" \ - $(CFLAGS) /Fo$(XMLSEC_CRYPTO_INTDIR_A)\ /c $< + $(CFLAGS) $(XMLSEC_OPENSSL_CFLAGS) /Fo$(XMLSEC_OPENSSL_INTDIR_A)\ /c $< +{$(XMLSEC_SRCDIR)}.c{$(XMLSEC_NSS_INTDIR_A)}.obj:: + $(CC) /D "LIBXML_STATIC" /D "LIBXSLT_STATIC" /D "XMLSEC_STATIC" \ + $(CFLAGS) $(XMLSEC_NSS_CFLAGS) /Fo$(XMLSEC_NSS_INTDIR_A)\ /c $< +{$(XMLSEC_NSS_SRCDIR)}.c{$(XMLSEC_NSS_INTDIR_A)}.obj:: + $(CC) /D "LIBXML_STATIC" /D "LIBXSLT_STATIC" /D "XMLSEC_STATIC" \ + $(CFLAGS) $(XMLSEC_NSS_CFLAGS) /Fo$(XMLSEC_NSS_INTDIR_A)\ /c $< # An implicit rule for strings file # Compiles xmlsec source. Uses the implicit rule for commands. @@ -398,11 +471,10 @@ $(XMLSEC_OBJS) : $(XMLSEC_INTDIR) $(XMLSEC_OBJS_A) : $(XMLSEC_INTDIR_A) # Compiles xmlsec-crypto source. Uses the implicit rule for commands. -$(XMLSEC_CRYPTO_OBJS) : $(XMLSEC_CRYPTO_INTDIR) - -# Compiles static xmlsec-crypto source. Uses the implicit rule for commands. -$(XMLSEC_CRYPTO_OBJS_A) : $(XMLSEC_CRYPTO_INTDIR_A) - +$(XMLSEC_OPENSSL_OBJS) : $(XMLSEC_OPENSSL_INTDIR) +$(XMLSEC_OPENSSL_OBJS_A) : $(XMLSEC_OPENSSL_INTDIR_A) +$(XMLSEC_NSS_OBJS) : $(XMLSEC_NSS_INTDIR) +$(XMLSEC_NSS_OBJS_A) : $(XMLSEC_NSS_INTDIR_A) # Creates the xmlsec shared object. $(BINDIR)\$(XMLSEC_SO) : $(BINDIR) $(XMLSEC_OBJS) $(LD) $(LDFLAGS) /DLL /VERSION:$(XMLSEC_VERSION_MAJOR).$(XMLSEC_VERSION_MINOR) \ @@ -413,16 +485,20 @@ $(BINDIR)\$(XMLSEC_SO) : $(BINDIR) $(XMLSEC_OBJS) $(BINDIR)\$(XMLSEC_A) : $(BINDIR) $(XMLSEC_OBJS_A) $(AR) $(ARFLAGS) /OUT:$(BINDIR)\$(XMLSEC_A) $(XMLSEC_OBJS_A) -# Creates the xmlsec-crypto shared object. -$(BINDIR)\$(XMLSEC_CRYPTO_SO) : $(BINDIR) $(XMLSEC_CRYPTO_OBJS) +# Creates the xmlsec-crypto shared object and archive. +$(BINDIR)\$(XMLSEC_OPENSSL_SO) : $(BINDIR) $(XMLSEC_OPENSSL_OBJS) $(LD) $(LDFLAGS) /DLL /VERSION:$(XMLSEC_VERSION_MAJOR).$(XMLSEC_VERSION_MINOR) \ - /IMPLIB:$(BINDIR)\$(XMLSEC_CRYPTO_IMP) /OUT:$(BINDIR)\$(XMLSEC_CRYPTO_SO) \ - $(XMLSEC_CRYPTO_OBJS) $(XMLSEC_IMP) $(SOLIBS) $(XMLSEC_CRYPTO_SOLIBS) - -# Creates the xmlsec-crypto archive. -$(BINDIR)\$(XMLSEC_CRYPTO_A) : $(BINDIR) $(XMLSEC_CRYPTO_OBJS_A) - $(AR) $(ARFLAGS) /OUT:$(BINDIR)\$(XMLSEC_CRYPTO_A) $(XMLSEC_CRYPTO_OBJS_A) + /IMPLIB:$(BINDIR)\$(XMLSEC_OPENSSL_IMP) /OUT:$(BINDIR)\$(XMLSEC_OPENSSL_SO) \ + $(XMLSEC_OPENSSL_OBJS) $(XMLSEC_IMP) $(SOLIBS) $(XMLSEC_OPENSSL_SOLIBS) +$(BINDIR)\$(XMLSEC_OPENSSL_A) : $(BINDIR) $(XMLSEC_OPENSSL_OBJS_A) + $(AR) $(ARFLAGS) /OUT:$(BINDIR)\$(XMLSEC_OPENSSL_A) $(XMLSEC_OPENSSL_OBJS_A) +$(BINDIR)\$(XMLSEC_NSS_SO) : $(BINDIR) $(XMLSEC_NSS_OBJS) + $(LD) $(LDFLAGS) /DLL /VERSION:$(XMLSEC_VERSION_MAJOR).$(XMLSEC_VERSION_MINOR) \ + /IMPLIB:$(BINDIR)\$(XMLSEC_NSS_IMP) /OUT:$(BINDIR)\$(XMLSEC_NSS_SO) \ + $(XMLSEC_NSS_OBJS) $(XMLSEC_IMP) $(SOLIBS) $(XMLSEC_NSS_SOLIBS) +$(BINDIR)\$(XMLSEC_NSS_A) : $(BINDIR) $(XMLSEC_NSS_OBJS_A) + $(AR) $(ARFLAGS) /OUT:$(BINDIR)\$(XMLSEC_NSS_A) $(XMLSEC_NSS_OBJS_A) # Creates the apps intermediate directory. $(XMLSEC_APPS_INTDIR) : @@ -438,7 +514,7 @@ $(BINDIR)\xmlsec.exe: $(BINDIR) $(XMLSEC_APPS_OBJS) $(LD) $(LDFLAGS) /OUT:$@ $(XMLSEC_IMP) $(XMLSEC_CRYPTO_IMP) $(APPLIBS) $(XMLSEC_APPS_OBJS) # Builds xmlsec and friends. Uses the implicit rule for commands. -$(APPS) : $(BINDIR) xmlsec xmlseca +$(BINDIR)\$(APP_NAME) : $(BINDIR) xmlsec xmlseca # Source dependences should be autogenerated somehow here, but how to # do it? I have no clue. diff --git a/win32/configure.js b/win32/configure.js index 6967ab60..a4017939 100644 --- a/win32/configure.js +++ b/win32/configure.js @@ -38,6 +38,10 @@ var verMicroXmlSec; /* Libxmlsec features. */ var withCrypto = "openssl"; +var withDefaultCrypto = "openssl"; +var withOpenSSL = 0; +var withOpenSSL096 = 0; +var withNss = 0; var withLibXSLT = 1; var withIconv = 1; @@ -88,7 +92,8 @@ function usage() txt += "Options can be specified in the form <option>=<value>, where the value is\n"; txt += "either 'yes' or 'no'.\n\n"; txt += "XmlSec Library options, default value given in parentheses:\n\n"; - txt += " crypto: Crypto engine: \"openssl\", \"openssl_096\", \"nss\" (\"" + withCrypto + "\");\n" + txt += " crypto: Crypto engines list, first is default: \"openssl\",\n"; + txt += " \"openssl_096\", \"nss\", (\"" + withCrypto + "\");\n" txt += " xslt: LibXSLT is used (" + (withLibXSLT? "yes" : "no") + ")\n"; txt += " iconv: Use the iconv library (" + (withIconv? "yes" : "no") + ")\n"; txt += "\nWin32 build options, default value given in parentheses:\n\n"; @@ -116,6 +121,7 @@ function usage() function discoverVersion() { var fso, cf, vf, ln, s; + fso = new ActiveXObject("Scripting.FileSystemObject"); cf = fso.OpenTextFile(configFile, 1); vf = fso.CreateTextFile(versionFile, true); @@ -142,7 +148,11 @@ function discoverVersion() vf.WriteLine("XMLSEC_SRCDIR=" + srcDir); vf.WriteLine("APPS_SRCDIR=" + srcDirApps); vf.WriteLine("BINDIR=" + binDir); - vf.WriteLine("WITH_CRYPTO=" + withCrypto); + vf.WriteLine("WITH_CRYPTO=" + withCrypto); + vf.WriteLine("WITH_DEFAULT_CRYPTO=" + withDefaultCrypto); + vf.WriteLine("WITH_OPENSSL=" + withOpenSSL); + vf.WriteLine("WITH_OPENSSL_096=" + withOpenSSL096); + vf.WriteLine("WITH_NSS=" + withNss); vf.WriteLine("WITH_LIBXSLT=" + (withLibXSLT ? "1" : "0")); vf.WriteLine("WITH_ICONV=" + (withIconv ? "1" : "0")); vf.WriteLine("DEBUG=" + (buildDebug? "1" : "0")); @@ -293,6 +303,31 @@ if (error != 0) { WScript.Quit(error); } +// Discover crypto support +var crlist, j; +crlist = withCrypto.split(","); +withCrypto = ""; +for (j = 0; j < crlist.length; j++) { + if (crlist[j] == "openssl") + withOpenSSL = 1; + else if (crlist[j] == "openssl_096") + withOpenSSL096 = 1; + else if (crlist[j] == "nss") + withNss = 1; + else { + WScript.Echo("Unknown crypto engine \"" + crlist[j] + "\" is found. Aborting."); + WScript.Quit(error); + } + withCrypto = withCrypto + " " + crlist[j]; +} +if ((withOpenSSL == 1) && (withOpenSSL096 == 1)) { + WScript.Echo("Only one of \"openssl\" and \"openssl_096\" could be specified. Aborting."); + WScript.Quit(error); +} +withDefaultCrypto = crlist[0]; +if (withDefaultCrypto == "openssl_096") + withDefaultCrypto = "openssl"; + // Discover the version. discoverVersion(); if (error != 0) { @@ -301,6 +336,7 @@ if (error != 0) { } WScript.Echo(baseName + " version: " + verMajorXmlSec + "." + verMinorXmlSec + "." + verMicroXmlSec); + // Configure libxmlsec. configureXmlSec(); if (error != 0) { @@ -318,6 +354,10 @@ WScript.Echo("Created Makefile."); var txtOut = "\nXMLSEC configuration\n"; txtOut += "----------------------------\n"; txtOut += " Use Crypto: " + withCrypto + "\n"; +txtOut += "Use Default Crypto: " + withDefaultCrypto + "\n"; +txtOut += " Use OpenSSL: " + boolToStr(withOpenSSL) + "\n"; +txtOut += " Use OpenSSL 096: " + boolToStr(withOpenSSL096) + "\n"; +txtOut += " Use NSS: " + boolToStr(withNss) + "\n"; txtOut += " Use LibXSLT: " + boolToStr(withLibXSLT) + "\n"; txtOut += " Use iconv: " + boolToStr(withIconv) + "\n"; txtOut += "\n"; diff --git a/win32/mycfg.bat b/win32/mycfg.bat index 898c875b..0901fea9 100644 --- a/win32/mycfg.bat +++ b/win32/mycfg.bat @@ -8,18 +8,10 @@ REM REM Aleksey Sanin <aleksey@aleksey.com> REM -REM SET ICONV=d:\sdk\bin\iconv -REM SET LIBXML2=d:\sdk\bin\libxml2 -REM SET LIBXSLT=d:\sdk\bin\libxslt -REM SET OPENSSL=d:\sdk\bin\openssl -REM SET XMLSEC_PREFIX=d:\sdk\bin\xmlsec -REM SET XMLSEC_INCLUDE=%ICONV%\include;%LIBXML2%\include;%LIBXSLT%\include;%OPENSSL%\include -REM SET XMLSEC_LIB=%ICONV%\lib;%LIBXML2%\lib;%LIBXSLT%\lib;%OPENSSL%\lib - SET XMLSEC_PREFIX=d:\sdk -SET XMLSEC_INCLUDE=%XMLSEC_PREFIX%\include -SET XMLSEC_LIB=%XMLSEC_PREFIX%\lib -SET XMLSEC_OPTIONS=static=no debug=yes xslt=yes crypto=openssl +SET XMLSEC_INCLUDE=%XMLSEC_PREFIX%\include;%XMLSEC_PREFIX%\include\mozilla;%XMLSEC_PREFIX%\include\mozilla\nspr;%XMLSEC_PREFIX%\include\mozilla\public;%XMLSEC_PREFIX%\include\mozilla\public\nss;%MSSDK_INCLUDE% +SET XMLSEC_LIB=%XMLSEC_PREFIX%\lib;%MSSDK_LIB% +SET XMLSEC_OPTIONS=static=no debug=yes xslt=yes crypto=openssl,nss del /F Makefile configure.txt cscript configure.js prefix=%XMLSEC_PREFIX% %XMLSEC_OPTIONS% include=%XMLSEC_INCLUDE% lib=%XMLSEC_LIB% |