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 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 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 83 int load_modules_all(const 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 111 int load_module (char *modulename, const 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_LAZY))!=NULL) break; 124 } 125 free(mdircpy); 126 } else { 127 strncpy(modulefile, modulename, sizeof(modulefile)-1); 128 if ((mh=dlopen(modulefile, RTLD_GLOBAL|RTLD_LAZY))==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 227 int init_modules(void) { return(DACT_MOD_FAIL); } 228 int unload_modules(void) { return(DACT_MOD_FAIL); } 229 int load_module(char *modulename, const char *options) { return(DACT_MOD_FAIL); } 230 int load_modules_all(const char *options) { return(DACT_MOD_FAIL); } 231 232 233 234 #endif |