1 /*
2 * Copyright (C) 2001, 2002, and 2003 Roy Keene
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * email: dact@rkeene.org
19 */
20
21
22 #include "dact.h"
23 #include "module.h"
24 #ifdef USE_MODULES
25 #ifdef HAVE_DLFCN_H
26 #include <dlfcn.h>
27 #endif
28 #include <stdio.h>
29 #ifdef HAVE_STRING_H
30 #include <string.h>
31 #endif
32 #ifdef HAVE_STDLIB_H
33 #include <stdlib.h>
34 #endif
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 #include <fcntl.h>
39 #ifdef HAVE_SYS_TYPES_H
40 #include <sys/types.h>
41 #endif
42 #ifdef HAVE_SYS_STAT_H
43 #include <sys/stat.h>
44 #endif
45 #ifdef HAVE_DIRENT_H
46 #include <dirent.h>
47 #endif
48 #include "algorithms.h"
49 #include "ciphers.h"
50 #include "parse.h"
51 #include "net.h"
52 #include "ui.h"
53
54 char moduledirectory[2048] = "@@HOME@@/.dact/@@OSNM@@-@@ARCH@@/";
55 void *modules[256];
56 int modules_initialized = 0;
57 int modules_count = 0;
58
init_modules(void)59 int init_modules (void) {
60 int i;
61
62 if (modules_initialized!=0) return(DACT_MOD_FAIL);
63 modules_initialized=1;
64
65 for (i=0;i<256;i++) {
66 modules[i]=NULL;
67 }
68 return(DACT_MOD_OK);
69 }
70
unload_modules(void)71 int unload_modules (void) {
72 int i;
73
74 if (modules_initialized==0) return(DACT_MOD_FAIL);
75
76 for (i=0;i<256;i++) {
77 if (modules[i]!=NULL)
78 dlclose(modules[i]);
79 }
80 return(DACT_MOD_OK);
81 }
82
load_modules_all(const unsigned char * options)83 int load_modules_all(const unsigned char *options) {
84 #ifdef HAVE_DIRENT_H
85 struct dirent *dinfo;
86 char *mdircpy, *tmpbuf, *mbuf, *fname, fullfname[1024];
87 DIR *dirtype;
88
89 mdircpy=parse_url_subst(moduledirectory, "");
90 mbuf=mdircpy;
91 while ((tmpbuf=strsep(&mbuf, ":"))) {
92 if ((dirtype=opendir(tmpbuf))==NULL) continue;
93 while ((dinfo=readdir(dirtype))!=NULL) {
94 fname=dinfo->d_name;
95 if (strcmp(fname+strlen(fname)-3,".so")==0) {
96 strncpy(fullfname, tmpbuf, sizeof(fullfname));
97 strncat(fullfname, "/", sizeof(fullfname)-strlen(fullfname));
98 strncat(fullfname, fname, sizeof(fullfname)-strlen(fullfname));
99 load_module(fullfname, options);
100 }
101 }
102 closedir(dirtype);
103 }
104 free(mdircpy);
105 #else
106 PRINTERR("I don't know how to handle this.")
107 #endif
108 return(DACT_MOD_OK);
109 }
110
load_module(char * modulename,const unsigned char * options)111 int load_module (char *modulename, const unsigned char *options) {
112 char modulefile[256], *tmpbuf, *mbuf, *mdircpy;
113 void *mh=NULL;
114 uint32_t algo_num, module_type=DACT_MOD_TYPE_COMP;
115 uint32_t dc_ver=0, dc_req=0, dact_ver;
116 char *dc_url_get=NULL, *dc_url_ver=NULL, *dc_sign=NULL;
117
118 if (strchr(modulename,'/')==NULL) {
119 mdircpy=parse_url_subst(moduledirectory, "");
120 mbuf=mdircpy;
121 while ((tmpbuf=strsep(&mbuf, ":"))) {
122 snprintf(modulefile, sizeof(modulefile)-1, "%s/%s.so",tmpbuf,modulename);
123 if ((mh=dlopen(modulefile, RTLD_GLOBAL|RTLD_NOW))!=NULL) break;
124 }
125 free(mdircpy);
126 } else {
127 strncpy(modulefile, modulename, sizeof(modulefile)-1);
128 if ((mh=dlopen(modulefile, RTLD_GLOBAL|RTLD_NOW))==NULL) {
129 PRINTERR("Could not load module.");
130 return(DACT_MOD_FAIL);
131 }
132 }
133 if (!mh) return(DACT_MOD_FAIL);
134
135 if (dlsym(mh,"DC_NUM")==NULL \
136 || dlsym(mh, "DC_NAME")==NULL \
137 || dlsym(mh, "DC_ALGO")==NULL) {
138 dact_ui_status(DACT_UI_LVL_SPEC, modulefile);
139 dact_ui_status_append(DACT_UI_LVL_SPEC, " is not a dact module.");
140 dlclose(mh);
141 return(DACT_MOD_FAIL);
142 }
143
144 if (dlsym(mh, "DC_TYPE")!=NULL) {
145 memcpy(&module_type,dlsym(mh,"DC_TYPE"),sizeof(module_type));
146 }
147
148 memcpy(&algo_num,dlsym(mh,"DC_NUM"),sizeof(algo_num));
149
150 if (dlsym(mh, "DC_VER")!=NULL) memcpy(&dc_ver, dlsym(mh, "DC_VER"), sizeof(dc_ver));
151 if (dlsym(mh, "DC_REQUIRE")!=NULL) memcpy(&dc_req, dlsym(mh, "DC_REQUIRE"), sizeof(dc_req));
152 if (dlsym(mh, "DC_URL_GET")!=NULL) memcpy(&dc_url_get, dlsym(mh, "DC_URL_GET"), sizeof(dc_url_get));
153 if (dlsym(mh, "DC_URL_VER")!=NULL) memcpy(&dc_url_ver, dlsym(mh, "DC_URL_VER"), sizeof(dc_url_ver));
154 if (dlsym(mh, "DC_SIGN")!=NULL) memcpy(&dc_sign, dlsym(mh, "DC_SIGN"), sizeof(dc_sign));
155
156 if (dc_url_get!=NULL && dc_url_ver!=NULL && dc_ver!=0 && modulename[0]!='/') {
157 dact_upgrade_file(modulename, dc_url_get, dc_url_ver, dc_ver, NULL, options);
158 }
159
160 if (dc_req!=0) {
161 dact_ver=(DACT_VER_MAJOR<<16)|(DACT_VER_MINOR<<8)|(DACT_VER_REVISION);
162 switch (dc_req&0xff000000) {
163 case DACT_MOD_REQ_ATLEAST:
164 if (dact_ver<(dc_req&0xffffff)) {
165 fprintf(stderr, "%s requires atleast DACT %i.%i.%i, this is DACT %i.%i.%i\n",modulefile,DACT_VER_PARTS(dc_req), DACT_VER_MAJOR, DACT_VER_MINOR, DACT_VER_REVISION);
166 dlclose(mh);
167 return(DACT_MOD_FAIL);
168 }
169 break;
170 case DACT_MOD_REQ_EXACTLY:
171 if ((dc_req&0xffffff)!=dact_ver) {
172 fprintf(stderr, "%s requires DACT %i.%i.%i, this is DACT %i.%i.%i\n",modulefile, DACT_VER_PARTS(dc_req), DACT_VER_MAJOR, DACT_VER_MINOR, DACT_VER_REVISION);
173 dlclose(mh);
174 return(DACT_MOD_FAIL);
175 }
176 break;
177 case DACT_MOD_REQ_ATMOST:
178 if (dact_ver>(dc_req&0xffffff)) {
179 fprintf(stderr, "%s requires atmost DACT %i.%i.%i, this is DACT %i.%i.%i\n",modulefile,DACT_VER_PARTS(dc_req), DACT_VER_MAJOR, DACT_VER_MINOR, DACT_VER_REVISION);
180 dlclose(mh);
181 return(DACT_MOD_FAIL);
182 }
183 break;
184 }
185 }
186
187
188
189 if (modules_count<255) {
190 modules[modules_count++]=mh;
191 }
192
193 switch (module_type) {
194 case DACT_MOD_TYPE_COMP:
195
196 if (algo_num>=((sizeof(algorithms))/(sizeof(*algorithms)))) return(DACT_MOD_FAIL);
197 if (algorithms[algo_num]!=DACT_FAILED_ALGO && algorithms[algo_num]!=NULL) {
198 dlclose(mh);
199 return(DACT_MOD_FAIL);
200 }
201
202 memcpy(&algorithms[algo_num],dlsym(mh, "DC_ALGO"),sizeof(algorithms[0]));
203 memcpy(&algorithm_names[algo_num],dlsym(mh,"DC_NAME"),sizeof(algorithm_names[0]));
204
205
206 return(DACT_MOD_OK);
207 case DACT_MOD_TYPE_ENC:
208 if (algo_num>=CIPHER_COUNT) {
209 printf("Encryption algorithm number too high, ignoring %i\n", algo_num);
210 return(DACT_MOD_FAIL);
211 }
212 if (ciphers[algo_num]!=DACT_FAILED_ALGO && ciphers[algo_num]!=NULL) {
213 return(DACT_MOD_FAIL);
214 }
215 memcpy(&ciphers[algo_num],dlsym(mh, "DC_ALGO"),sizeof(algorithms[0]));
216 memcpy(&ciphers_name[algo_num],dlsym(mh, "DC_NAME"),sizeof(ciphers_name[0]));
217 return(DACT_MOD_OK);
218 }
219 return(DACT_MOD_FAIL);
220 }
221 #else
222 char moduledirectory[2048] = ".";
223 void *modules[256];
224 int modules_initialized = 0;
225 int modules_count = 0;
226
init_modules(void)227 int init_modules(void) { return(DACT_MOD_FAIL); }
unload_modules(void)228 int unload_modules(void) { return(DACT_MOD_FAIL); }
load_module(char * modulename,const unsigned char * options)229 int load_module(char *modulename, const unsigned char *options) { return(DACT_MOD_FAIL); }
load_modules_all(const unsigned char * options)230 int load_modules_all(const unsigned char *options) { return(DACT_MOD_FAIL); }
231
232
233
234 #endif
235