The big extension module removal.
[gnupg.git] / cipher / idea-stub.c
1 /* idea-stub.c - Dummy module for the deprecated IDEA cipher.
2  *      Copyright (C) 2002 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 /* IDEA is a patented algorithm and therefore the use of IDEA in
22    countries where this patent is valid can not be allowed due to the
23    terms of the GNU General Public License.  Those restrictions are
24    there to help protecting the freedom of software.  For more
25    information on the nonsense of software patents and the general
26    problem with this, please see http://www.noepatents.org.
27
28    However for research purposes and in certain situations it might be
29    useful to use this algorithm anyway.  
30
31    We provide this stub which will dynload a idea module and is only 
32    used if the configure run did't found statically linked file.
33    See http://www.gnupg.org/why-not-dea.html for details.
34 */
35
36 #include <config.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #ifdef HAVE_DL_DLOPEN
42   #include <dlfcn.h>
43 #endif
44 #ifdef __MINGW32__
45   #include <windows.h>
46 #endif
47 #include "util.h"
48 #include "algorithms.h"
49
50 #ifndef RTLD_NOW
51   #define RTLD_NOW  1
52 #endif
53
54
55 #ifdef __MINGW32__
56 #define HAVE_DL_DLOPEN
57 #define USE_DYNAMIC_LINKING
58
59 static int last_error = 0;
60     
61 void*
62 dlopen (const char *pathname, int mode)
63 {
64   void *h = LoadLibrary (pathname);
65   if (!h) 
66     {
67       log_error ("LoadLibrary failed ec=%d\n", (int)GetLastError());
68       last_error = 1;
69       return NULL;
70     }
71   return h;
72 }
73
74 int
75 dlclose ( void *handle )
76 {
77   last_error = 0;
78   return FreeLibrary (handle);
79 }
80
81 char*
82 dlerror (void)
83 {
84   static char dlerrstr[10];
85   if (last_error)
86     {
87       sprintf(dlerrstr, "%d", (int)GetLastError() );
88       return dlerrstr;
89     }
90   return NULL;
91 }
92
93 void*
94 dlsym ( void *handle, const char *name )
95 {
96   void *h = GetProcAddress (handle, name);
97   if (!h)
98     {
99       log_error ("GetProcAddress failed ec=%d\n", (int)GetLastError());
100       last_error = 1;
101     }
102   return h;
103 }
104 #endif /*__MINGW32__*/
105
106 /* We do only support dlopen and the Windows emulation of it. */
107 #ifndef HAVE_DL_DLOPEN
108 #undef USE_DYNAMIC_LINKING
109 #endif
110
111
112 static void *
113 load_module (const char *name)
114 {
115 #ifdef USE_DYNAMIC_LINKING
116   const char *err;
117   void *handle;
118   void *sym;
119
120 #ifndef __MINGW32__
121   /* Make sure we are not setuid. */
122   if (getuid() != geteuid())
123     log_bug("trying to load an extension while still setuid\n");
124 #endif
125
126   handle = dlopen (name, RTLD_NOW);
127   if (!name)
128     {
129       /*log_error ("error loading module `%s': %s\n", name, dlerror());*/
130       goto failure;
131     }
132
133   sym = dlsym (handle, "idea_get_info");
134   if (dlerror ())
135     sym = dlsym (handle, "_idea_get_info");
136   if ((err=dlerror())) 
137     {
138       log_info ("invalid module `%s': %s\n", name, err);
139       goto failure;
140     }
141
142   return sym;
143   
144  failure:
145   if (handle)
146       dlclose (handle);
147 #endif /*USE_DYNAMIC_LINKING*/
148   return NULL;
149 }
150
151
152 const char *
153 idea_get_info( int algo, size_t *keylen,
154                    size_t *blocksize, size_t *contextsize,
155                    int  (**r_setkey)( void *c, byte *key, unsigned keylen ),
156                    void (**r_encrypt)( void *c, byte *outbuf, byte *inbuf ),
157                    void (**r_decrypt)( void *c, byte *outbuf, byte *inbuf )
158                  )
159 {
160   static int initialized;
161   static const char * (*info_fnc)(int, size_t*, size_t*, size_t*,
162                                   int  (**)( void *, byte *, unsigned),
163                                   void (**)( void *, byte *, byte *),
164                                   void (**)( void *, byte *, byte *));
165   const char *rstr;
166   int i;
167
168   if (!initialized)
169     {
170       initialized = 1;
171       for (i=0; (rstr = dynload_enum_module_names (i)); i++)
172         {
173           info_fnc = load_module (rstr);
174           if (info_fnc)
175             break;
176         }
177     }
178   if (!info_fnc)
179     return NULL; /* dynloadable module not found. */
180   rstr = info_fnc (algo, keylen, blocksize, contextsize,
181                    r_setkey, r_encrypt, r_decrypt);
182   if (rstr && *keylen == 128 && *blocksize == 8
183       && *r_setkey && *r_encrypt && r_decrypt)
184     return rstr;
185   return NULL;
186 }
187