diff options
Diffstat (limited to 'cipher')
-rw-r--r-- | cipher/ChangeLog | 8 | ||||
-rw-r--r-- | cipher/Makefile.am | 6 | ||||
-rw-r--r-- | cipher/dynload.c | 84 | ||||
-rw-r--r-- | cipher/rand-unix.c | 8 |
4 files changed, 98 insertions, 8 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog index ddd34b65c..99cd30128 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,11 @@ +Thu Oct 15 11:47:57 1998 Werner Koch ([email protected]) + + * dynload.c: Support for DLD + +Wed Oct 14 12:13:07 1998 Werner Koch ([email protected]) + + * rand-unix.c: Now uses names from configure for /dev/random. + 1998-10-10 SL Baur <[email protected]> * Makefile.am: fix sed -O substitutions to catch -O6, etc. diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 298e0f32d..e151de578 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -11,6 +11,8 @@ else pkglib_PROGRAMS = endif +DYNLINK_MOD_CFLAGS = @DYNLINK_MOD_CFLAGS@ + libcipher_a_SOURCES = cipher.c \ pubkey.c \ @@ -48,11 +50,11 @@ EXTRA_twofish_SOURCES = twofish.c tiger: $(srcdir)/tiger.c - `echo $(COMPILE) -shared -fPIC -lc -o tiger $(srcdir)/tiger.c | \ + `echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o tiger $(srcdir)/tiger.c | \ sed -e 's/-O[2-9]*/-O1/' ` twofish: $(srcdir)/twofish.c - `echo $(COMPILE) -shared -fPIC -lc -o twofish $(srcdir)/twofish.c | \ + `echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o twofish $(srcdir)/twofish.c | \ sed -e 's/-O[0-9]*/ /' ` diff --git a/cipher/dynload.c b/cipher/dynload.c index 0cbbda2c1..ff40dafff 100644 --- a/cipher/dynload.c +++ b/cipher/dynload.c @@ -25,6 +25,8 @@ #include <unistd.h> #ifdef HAVE_DL_DLOPEN #include <dlfcn.h> +#elif defined(HAVE_DLD_DLD_LINK) + #include <dld.h> #endif #include "util.h" #include "cipher.h" @@ -37,7 +39,11 @@ typedef struct ext_list { struct ext_list *next; + #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 */ @@ -53,6 +59,14 @@ typedef struct { void *sym; } ENUMCONTEXT; + +#ifdef HAVE_DLD_DLD_LINK +static char *mainpgm_path; +static int did_dld_init; +static int dld_available; +#endif + + /**************** * Register an extension module. The last registered module will * be loaded first. A name may have a list of classes @@ -62,13 +76,20 @@ typedef struct { * 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 -register_cipher_extension( const char *fname ) +register_cipher_extension( const char *mainpgm, const char *fname ) { EXTLIST r, el; char *p, *pe; + #ifdef HAVE_DLD_DLD_LINK + if( !mainpgm_path && mainpgm && *mainpgm ) + mainpgm_path = m_strdup(mainpgm); + #endif if( *fname != '/' ) { /* do tilde expansion etc */ char *p ; @@ -110,16 +131,22 @@ load_extension( EXTLIST el ) { #ifdef USE_DYNAMIC_LINKING char **name; - void *sym; + #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() ); @@ -130,6 +157,38 @@ load_extension( EXTLIST el ) 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("gnupgext_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( g10_opt_verbose ) log_info("%s: %s%s%s%s\n", el->name, *name, @@ -137,13 +196,31 @@ load_extension( EXTLIST el ) el->hintstr? el->hintstr:"", el->hintstr? ")":""); + #ifdef HAVE_DL_DLOPEN sym = dlsym(el->handle, "gnupgext_enum_func"); 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("gnupgext_enum_func"); + if( !addr ) { + log_error("%s: invalid gnupg extension: %s\n", + el->name, dld_strerror(dld_errno) ); + goto failure; + } + rc = dld_function_executable_p("gnupgext_enum_func"); + 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( g10_opt_verbose > 1 ) { /* list the contents of the module */ while( (sym = (*el->enumfunc)(0, &seq, &class, &vers)) ) { @@ -166,13 +243,16 @@ load_extension( EXTLIST el ) } } } + #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; diff --git a/cipher/rand-unix.c b/cipher/rand-unix.c index 33f964d58..b9423e0d1 100644 --- a/cipher/rand-unix.c +++ b/cipher/rand-unix.c @@ -89,10 +89,10 @@ fast_random_poll() } -#ifdef HAVE_DEV_RANDOM /* we have the /dev/random device */ +#ifdef HAVE_DEV_RANDOM /* we have the /dev/random devices */ /**************** - * Used to open the Linux /dev/random device + * Used to open the Linux and xBSD /dev/random devices */ static int open_device( const char *name, int minor ) @@ -126,12 +126,12 @@ read_random_source( byte *buffer, size_t length, int level ) if( level >= 2 ) { if( fd_random == -1 ) - fd_random = open_device( "/dev/random", 8 ); + fd_random = open_device( NAME_OF_DEV_RANDOM, 8 ); fd = fd_random; } else { if( fd_urandom == -1 ) - fd_urandom = open_device( "/dev/urandom", 9 ); + fd_urandom = open_device( NAME_OF_DEV_URANDOM, 9 ); fd = fd_urandom; } do { |