* rndegd.c (rndegd_constructor): Fixed name of register function
[libgcrypt.git] / cipher / dynload.c
index a34c288..711468a 100644 (file)
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
+/*
+ Note: We don't support dynamically loaded modules anymore.  This
+ would be troublesome for thread-safety and it is better done by the
+ application.  One of the next releases will have an API to support
+ additional ciphers.
+*/
+
+
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#ifdef HAVE_DL_DLOPEN
-  #include <dlfcn.h>
-#elif defined(HAVE_DLD_DLD_LINK)
-  #include <dld.h>
-#elif defined(HAVE_DL_SHL_LOAD)
-  #include <dl.h>
-  #include <errno.h>
-#endif
 #include "g10lib.h"
 #include "cipher.h"
 #include "dynload.h"
 
-#ifdef WITH_SYMBOL_UNDERSCORE
-  #define SYMBOL_VERSION "_gnupgext_version"
-  #define SYMBOL_ENUM   "_gnupgext_enum_func"
-#else
-  #define SYMBOL_VERSION "gnupgext_version"
-  #define SYMBOL_ENUM   "gnupgext_enum_func"
-#endif
-
-
-#ifndef RTLD_NOW
-  #define RTLD_NOW  1
-#endif
-
-#ifdef HAVE_DL_SHL_LOAD  /* HPUX has shl_load instead of dlopen */
-#define HAVE_DL_DLOPEN
-#define dlopen(PATHNAME,MODE) \
-    ((void *) shl_load(PATHNAME, DYNAMIC_PATH | \
-             (((MODE) & RTLD_NOW) ? BIND_IMMEDIATE : BIND_DEFERRED), 0L))
-#define dlclose(HANDLE) shl_unload((shl_t) (HANDLE))
-#define dlerror() (errno == 0 ? NULL : strerror(errno))
-
-static void *
-dlsym(void *handle, char *name)
-{
-    void *addr;
-    if (shl_findsym((shl_t *)&handle,name,(short)TYPE_UNDEFINED,&addr) != 0) {
-      return NULL;
-    }
-    return addr;
-}
-#endif /*HAVE_DL_SHL_LOAD*/
-
-
 
 typedef struct ext_list {
     struct ext_list *next;
     int internal;
-  #ifdef HAVE_DL_DLOPEN
-    void *handle; /* handle from dlopen() */
-  #else
     int handle;   /* if the function has been loaded, this is true */
-  #endif
     int  failed;  /* already tried but failed */
     void * (*enumfunc)(int, int*, int*, int*);
     char *hintstr; /* pointer into name */
@@ -94,86 +57,6 @@ typedef struct {
 } ENUMCONTEXT;
 
 
-#ifdef HAVE_DLD_DLD_LINK
-static char *mainpgm_path;
-static int did_dld_init;
-static int dld_available;
-#endif
-
-
-static int
-cmp_filenames( const char *a, const char *b )
-{
-    /* ? check whether this is an absolute filename and
-     * resolve symlinks?
-     */
-  #ifdef HAVE_DRIVE_LETTERS
-    return stricmp(a,b);
-  #else
-    return strcmp(a,b);
-  #endif
-}
-
-
-/****************
- * Register an extension module.  The last registered module will
- * be loaded first.  A name may have a list of classes
- * appended; e.g:
- *     mymodule.so(1:17,3:20,3:109)
- * means that this module provides digest algorithm 17 and public key
- * algorithms 20 and 109.  This is only a hint but if it is there the
- * loader may decide to only load a module which claims to have a
- * requested algorithm.
- *
- * mainpgm is the path to the program which wants to load a module
- * it is only used in some environments.
- */
-void
-_gcry_register_cipher_extension( const char *mainpgm, const char *fname )
-{
-    EXTLIST r, el, intex;
-    char *p, *pe;
-
-  #ifdef HAVE_DLD_DLD_LINK
-    if( !mainpgm_path && mainpgm && *mainpgm )
-       mainpgm_path = m_strdup(mainpgm);
-  #endif
-    el = gcry_xcalloc( 1, sizeof *el + strlen(fname) );
-    strcpy(el->name, fname );
-
-    /* check whether we have a class hint */
-    if( (p=strchr(el->name,'(')) && (pe=strchr(p+1,')')) && !pe[1] ) {
-       *p = *pe = 0;
-       el->hintstr = p+1;
-    }
-    else
-       el->hintstr = NULL;
-
-    /* check that it is not already registered */
-    intex = NULL;
-    for(r = extensions; r; r = r->next ) {
-       if( !cmp_filenames(r->name, el->name) ) {
-           log_info("extension `%s' already registered\n", el->name );
-           gcry_free(el);
-           return;
-       }
-       else if( r->internal )
-           intex = r;
-    }
-    /* and register */
-    /* we put them after the internal extension modules */
-    /* this is so that the external modules do not get loaded */
-    /* as soon as the internal modules are requested */
-    if( intex ) {
-       el->next = intex->next;
-       intex->next = el;
-    }
-    else {
-       el->next = extensions;
-       extensions = el;
-    }
-}
-
 void
 _gcry_register_internal_cipher_extension(
                        const char *module_id,
@@ -188,7 +71,7 @@ _gcry_register_internal_cipher_extension(
 
     /* check that it is not already registered */
     for(r = extensions; r; r = r->next ) {
-       if( !cmp_filenames(r->name, el->name) ) {
+       if( !strcmp (r->name, el->name) ) {
            log_info("extension `%s' already registered\n", el->name );
            gcry_free(el);
            return;
@@ -196,11 +79,7 @@ _gcry_register_internal_cipher_extension(
     }
     /* and register */
     el->enumfunc = enumfunc;
-  #ifdef HAVE_DL_DLOPEN
-    el->handle = (void*)1;
-  #else
     el->handle = 1;
-  #endif
     el->next = extensions;
     extensions = el;
 }
@@ -209,132 +88,6 @@ _gcry_register_internal_cipher_extension(
 static int
 load_extension( EXTLIST el )
 {
-  #ifdef USE_DYNAMIC_LINKING
-    char **name;
-  #ifdef HAVE_DL_DLOPEN
-    const char *err;
-    int seq = 0;
-    int class, vers;
-    void *sym;
-  #else
-    unsigned long addr;
-    int rc;
-  #endif
-
-    /* make sure we are not setuid */
-    if( getuid() != geteuid() )
-       log_bug("trying to load an extension while still setuid\n");
-
-    /* now that we are not setuid anymore, we can safely load modules */
-  #ifdef HAVE_DL_DLOPEN
-    el->handle = dlopen(el->name, RTLD_NOW);
-    if( !el->handle ) {
-       log_error("%s: error loading extension: %s\n", el->name, dlerror() );
-       goto failure;
-    }
-    name = (char**)dlsym(el->handle, SYMBOL_VERSION);
-    if( (err=dlerror()) ) {
-       log_error("%s: not a gnupg extension: %s\n", el->name, err );
-       goto failure;
-    }
-  #else /* have dld */
-    if( !did_dld_init ) {
-       did_dld_init = 1;
-       if( !mainpgm_path )
-           log_error("DLD is not correctly initialized\n");
-       else {
-           rc = dld_init( dld_find_executable(mainpgm_path) );
-           if( rc )
-               log_error("DLD init failed: %s\n", dld_strerror(rc) );
-           else
-               dld_available = 1;
-       }
-    }
-    if( !dld_available ) {
-       log_error("%s: DLD not available\n", el->name );
-       goto failure;
-    }
-
-    rc = dld_link( el->name );
-    if( rc ) {
-       log_error("%s: error loading extension: %s\n",
-                                   el->name, dld_strerror(rc) );
-       goto failure;
-    }
-    addr = dld_get_symbol(SYMBOL_VERSION);
-    if( !addr ) {
-       log_error("%s: not a gnupg extension: %s\n",
-                               el->name, dld_strerror(dld_errno) );
-       goto failure;
-    }
-    name = (char**)addr;
-  #endif
-
-    if( _gcry_log_verbosity( 2 ) )
-       log_info("%s: %s%s%s%s\n", el->name, *name,
-                 el->hintstr? " (":"",
-                 el->hintstr? el->hintstr:"",
-                 el->hintstr? ")":"");
-
-  #ifdef HAVE_DL_DLOPEN
-    sym = dlsym(el->handle, SYMBOL_ENUM);
-    if( (err=dlerror()) ) {
-       log_error("%s: invalid gnupg extension: %s\n", el->name, err );
-       goto failure;
-    }
-    el->enumfunc = (void *(*)(int,int*,int*,int*))sym;
-  #else /* dld */
-    addr = dld_get_func(SYMBOL_ENUM);
-    if( !addr ) {
-       log_error("%s: invalid gnupg extension: %s\n",
-                               el->name, dld_strerror(dld_errno) );
-       goto failure;
-    }
-    rc = dld_function_executable_p(SYMBOL_ENUM);
-    if( rc ) {
-       log_error("%s: extension function is not executable: %s\n",
-                                       el->name, dld_strerror(rc) );
-       goto failure;
-    }
-    el->enumfunc = (void *(*)(int,int*,int*,int*))addr;
-    el->handle = 1; /* mark as usable */
-  #endif
-
-  #ifdef HAVE_DL_DLOPEN
-    if( _gcry_log_verbosity( 3 ) ) {
-       /* list the contents of the module */
-       while( (sym = (*el->enumfunc)(0, &seq, &class, &vers)) ) {
-           if( vers != 1 ) {
-               log_info("%s: ignoring func with version %d\n",el->name,vers);
-               continue;
-           }
-           switch( class ) {
-             case 11:
-             case 21:
-             case 31:
-               log_info("%s: provides %s algorithm %d\n", el->name,
-                               class == 11? "md"     :
-                               class == 21? "cipher" : "pubkey",
-                                                      *(int*)sym);
-               break;
-             default:
-               /*log_debug("%s: skipping class %d\n", el->name, class);*/
-               break;
-           }
-       }
-    }
-  #endif
-    return 0;
-
-  failure:
-  #ifdef HAVE_DL_DLOPEN
-    if( el->handle ) {
-       dlclose(el->handle);
-       el->handle = NULL;
-    }
-  #endif
-    el->failed = 1;
-  #endif /*USE_DYNAMIC_LINKING*/
     return -1;
 }