"Fossies" - the Fresh Open Source Software Archive

Member "libmcrypt-2.5.8/lib/mcrypt_extra.c" (19 Jan 2003, 9011 Bytes) of package /linux/privat/old/libmcrypt-2.5.8.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mcrypt_extra.c" see the Fossies "Dox" file reference documentation.

    1 /* 
    2  * Copyright (C) 1998,1999,2001 Nikos Mavroyanopoulos 
    3  *
    4  * This library is free software; you can redistribute it and/or modify it under the terms of the
    5  * GNU Library General Public License as published by the Free Software
    6  * Foundation; either version 2 of the License, or (at your option) any
    7  * later version.
    8  *
    9  * This library 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 GNU
   12  * Library General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU Library General Public
   15  * License along with this library; if not, write to the
   16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   17  * Boston, MA 02111-1307, USA.
   18  */
   19 
   20 /* $Id: mcrypt_extra.c,v 1.26 2002/12/17 10:53:34 nmav Exp $ */
   21 
   22 #include <libdefs.h>
   23 #include <bzero.h>
   24 #include <xmemory.h>
   25 #include <mcrypt_internal.h>
   26 
   27 int mcrypt_algorithm_module_ok(const char *file, const char *directory);
   28 int mcrypt_mode_module_ok(const char *file, const char *directory);
   29 
   30 void *mcrypt_dlopen(mcrypt_dlhandle * handle, const char *a_directory,
   31             const char *m_directory, const char *filename);
   32 
   33 #ifdef HAVE_READDIR_R
   34 # define MAXPATHLEN 256
   35 #endif
   36 
   37 WIN32DLL_DEFINE char *mcrypt_readdir(DIR * dirstream)
   38 {
   39 
   40     char *result;
   41     struct dirent *ret = NULL;
   42 #ifdef HAVE_READDIR_R
   43     struct dirent ret2[sizeof(struct dirent) + MAXPATHLEN];
   44 #endif
   45 
   46 #ifdef HAVE_READDIR_R
   47     readdir_r(dirstream, ret2, &ret);
   48 #else
   49     ret = readdir(dirstream);
   50 #endif
   51     if (ret == NULL)
   52         return NULL;
   53 
   54     result = strdup(ret->d_name);
   55     if (result == NULL) {
   56         return NULL;
   57     }
   58 
   59     return result;
   60 
   61 }
   62 
   63 extern const mcrypt_preloaded mps[];
   64 
   65 WIN32DLL_DEFINE char **mcrypt_list_algorithms(const char *libdir,
   66                           int *size)
   67 {
   68     DIR *pdir;
   69     char directory[512];
   70     char *dirname;
   71     char **filename = NULL, *ptr;
   72     int tmpsize, i = 0;
   73 
   74 
   75     *size = 0;
   76 
   77     while (mps[i].name != 0 || mps[i].address != 0) {
   78         if (mps[i].name != NULL && mps[i].address == NULL) {
   79             if (mcrypt_algorithm_module_ok(mps[i].name, NULL) >
   80                 0) {
   81                 filename =
   82                     realloc(filename,
   83                         ((*size) +
   84                          1) * sizeof(char *));
   85                 if (filename == NULL) {
   86                     goto freeall;
   87                 }
   88                 filename[*size] = strdup(mps[i].name);
   89                 if (filename[*size] == NULL)
   90                     goto freeall;
   91                 (*size)++;
   92             }
   93         }
   94         i++;
   95     }
   96 
   97 #ifdef USE_LTDL
   98 
   99     if (libdir == NULL) {
  100         strncpy(directory, LIBDIR, sizeof(directory)-1);
  101     } else {
  102         strncpy(directory, libdir, sizeof(directory)-1);
  103     }
  104     directory[ sizeof(directory)-1] = 0;
  105 
  106     pdir = opendir(directory);
  107     if (pdir == NULL) {
  108 #ifdef DEBUG
  109         fprintf(stderr, "Unable to open directory %s.\n",
  110             directory);
  111 #endif
  112         return filename;
  113     }
  114 
  115     for (;;) {
  116         dirname = mcrypt_readdir(pdir);
  117         if (dirname != NULL) {
  118             tmpsize = strlen(dirname);
  119             if (tmpsize > 3) {
  120 
  121                 if (mcrypt_algorithm_module_ok
  122                     (dirname, directory) > 0) {
  123                     ptr = strrchr(dirname, '.');
  124                     if (ptr != NULL) {
  125                         *ptr = '\0';
  126                         tmpsize = strlen(dirname);
  127                     }
  128 
  129                     if (_mcrypt_search_symlist_lib
  130                         (dirname) != NULL) {
  131                         free(dirname);
  132                         continue;   /* it's already in the list,
  133                                  * since it's included in the lib.
  134                                  */
  135                     }
  136 
  137                     filename =
  138                         realloc(filename,
  139                             (*size +
  140                              1) * sizeof(char *));
  141                     if (filename == NULL) {
  142                         free(dirname);
  143                         goto freeall;
  144                     }
  145 
  146                     filename[*size] = strdup(dirname);
  147                     if (filename[*size] == NULL) {
  148                         free(dirname);
  149                         goto freeall;
  150                     }
  151                     (*size)++;
  152                 }
  153             }
  154             free(dirname);
  155         } else break;
  156     }
  157 
  158 
  159     closedir(pdir);
  160 
  161 #endif
  162 
  163     return filename;
  164 
  165       freeall:
  166     for (i = 0; i < (*size); i++) {
  167         free(filename[i]);
  168     }
  169     free(filename);
  170     return NULL;
  171 }
  172 
  173 WIN32DLL_DEFINE char **mcrypt_list_modes(const char *libdir, int *size)
  174 {
  175     DIR *pdir;
  176     char directory[512];
  177     char *dirname;
  178     char **filename = NULL, *ptr;
  179     int tmpsize;
  180     int i = 0;
  181 
  182     *size = 0;
  183 
  184     while (mps[i].name != 0 || mps[i].address != 0) {
  185         if (mps[i].name != NULL && mps[i].address == NULL) {
  186             if (mcrypt_mode_module_ok(mps[i].name, NULL) > 0) {
  187                 filename =
  188                     realloc(filename,
  189                         (*size + 1) * sizeof(char *));
  190                 if (filename == NULL) {
  191                     goto freeall;
  192                 }
  193                 filename[*size] = strdup(mps[i].name);
  194                 if (filename[*size] == NULL)
  195                     goto freeall;
  196                 (*size)++;
  197             }
  198         }
  199         i++;
  200     }
  201 
  202 #ifdef USE_LTDL
  203 
  204     if (libdir == NULL) {
  205         strncpy(directory, LIBDIR, sizeof(directory)-1);
  206     } else {
  207         strncpy(directory, libdir, sizeof(directory)-1);
  208     }
  209     directory[ sizeof(directory)-1] = 0;
  210 
  211     pdir = opendir(directory);
  212     if (pdir == NULL) {
  213 #ifdef DEBUG
  214         fprintf(stderr, "Unable to open directory %s.\n",
  215             directory);
  216 #endif
  217         return filename;
  218     }
  219 
  220     for (;;) {
  221 
  222         dirname = mcrypt_readdir(pdir);
  223         if (dirname != NULL) {
  224             tmpsize = strlen(dirname);
  225             if (tmpsize > 3) {
  226                 if (mcrypt_mode_module_ok
  227                     (dirname, directory) > 0) {
  228 
  229                     ptr = strrchr(dirname, '.');
  230                     if (ptr != NULL) {
  231                         *ptr = '\0';
  232                         tmpsize = strlen(dirname);
  233                     }
  234                     if (_mcrypt_search_symlist_lib
  235                         (dirname) != NULL) {
  236                         free(dirname);
  237                         continue;   /* it's already in the list,
  238                                  * since it's included in the lib.
  239                                  */
  240                     }
  241                     filename =
  242                         realloc(filename,
  243                             (*size +
  244                              1) * sizeof(char *));
  245                     if (filename == NULL) {
  246                         free(dirname);
  247                         goto freeall;
  248                     }
  249 
  250                     filename[*size] = strdup(dirname);
  251                     if (filename[*size] == NULL) {
  252                         free(dirname);
  253                         goto freeall;
  254                     }
  255                     (*size)++;
  256                 }
  257             }
  258             free(dirname);
  259         } else {
  260             break;
  261         }
  262 
  263     }
  264 
  265     closedir(pdir);
  266 #endif
  267 
  268     return filename;
  269 
  270       freeall:
  271     for (i = 0; i < (*size); i++) {
  272         free(filename[i]);
  273     }
  274     free(filename);
  275     return NULL;
  276 }
  277 
  278 WIN32DLL_DEFINE void mcrypt_free_p(char **p, int size)
  279 {
  280     int i;
  281 
  282     for (i = 0; i < size; i++) {
  283         free(p[i]);
  284     }
  285     free(p);
  286 }
  287 
  288 WIN32DLL_DEFINE
  289     int mcrypt_algorithm_module_ok(const char *file, const char *directory)
  290 {
  291     word32 ret = 1;
  292     mcrypt_dlhandle _handle;
  293     void *rr;
  294     int (*_version) (void);
  295 
  296     if (file == NULL && directory == NULL) {
  297         return MCRYPT_UNKNOWN_ERROR;
  298     }
  299 
  300     if (lt_dlinit() != 0) {
  301         return MCRYPT_UNKNOWN_ERROR;
  302     }
  303 
  304     rr = mcrypt_dlopen(&_handle, directory, NULL, file);
  305 
  306     if (!rr) {
  307         lt_dlexit();
  308         return MCRYPT_UNKNOWN_ERROR;
  309     }
  310 
  311 
  312     _version = mcrypt_dlsym(_handle, "_mcrypt_algorithm_version");
  313 
  314     if (_version == NULL) {
  315         mcrypt_dlclose(_handle);
  316         lt_dlexit();
  317         return MCRYPT_UNKNOWN_ERROR;
  318     }
  319 
  320     ret = _version();
  321 
  322     mcrypt_dlclose(_handle);
  323 
  324     lt_dlexit();
  325 
  326     return ret;
  327 
  328 }
  329 
  330 WIN32DLL_DEFINE
  331     int mcrypt_mode_module_ok(const char *file, const char *directory)
  332 {
  333     word32 ret;
  334     mcrypt_dlhandle _handle;
  335     void *rr;
  336     int (*_version) (void);
  337 
  338     if (file == NULL && directory == NULL) {
  339         return MCRYPT_UNKNOWN_ERROR;
  340     }
  341 
  342     if (lt_dlinit() != 0) {
  343         return MCRYPT_UNKNOWN_ERROR;
  344     }
  345 
  346     rr = mcrypt_dlopen(&_handle, directory, NULL, file);
  347     if (!rr) {
  348         lt_dlexit();
  349         return MCRYPT_UNKNOWN_ERROR;
  350     }
  351 
  352 
  353     _version = mcrypt_dlsym(_handle, "_mcrypt_mode_version");
  354 
  355     if (_version == NULL) {
  356         mcrypt_dlclose(_handle);
  357         lt_dlexit();
  358         return MCRYPT_UNKNOWN_ERROR;
  359     }
  360 
  361     ret = _version();
  362 
  363     mcrypt_dlclose(_handle);
  364     lt_dlexit();
  365 
  366     return ret;
  367 
  368 }
  369 
  370 /* Taken from libgcrypt */
  371 
  372 static const char *parse_version_number(const char *s, int *number)
  373 {
  374     int val = 0;
  375 
  376     if (*s == '0' && isdigit(s[1]))
  377         return NULL;    /* leading zeros are not allowed */
  378     for (; isdigit(*s); s++) {
  379         val *= 10;
  380         val += *s - '0';
  381     }
  382     *number = val;
  383     return val < 0 ? NULL : s;
  384 }
  385 
  386 
  387 static const char *parse_version_string(const char *s, int *major,
  388                     int *minor, int *micro)
  389 {
  390     s = parse_version_number(s, major);
  391     if (!s || *s != '.')
  392         return NULL;
  393     s++;
  394     s = parse_version_number(s, minor);
  395     if (!s || *s != '.')
  396         return NULL;
  397     s++;
  398     s = parse_version_number(s, micro);
  399     if (!s)
  400         return NULL;
  401     return s;       /* patchlevel */
  402 }
  403 
  404 /****************
  405  * Check that the the version of the library is at minimum the requested one
  406  * and return the version string; return NULL if the condition is not
  407  * satisfied.  If a NULL is passed to this function, no check is done,
  408  * but the version string is simply returned.
  409  */
  410 const char *mcrypt_check_version(const char *req_version)
  411 {
  412     const char *ver = VERSION;
  413     int my_major, my_minor, my_micro;
  414     int rq_major, rq_minor, rq_micro;
  415     const char *my_plvl, *rq_plvl;
  416 
  417     if (!req_version)
  418         return ver;
  419 
  420     my_plvl =
  421         parse_version_string(ver, &my_major, &my_minor, &my_micro);
  422     if (!my_plvl)
  423         return NULL;    /* very strange our own version is bogus */
  424     rq_plvl = parse_version_string(req_version, &rq_major, &rq_minor,
  425                        &rq_micro);
  426     if (!rq_plvl)
  427         return NULL;    /* req version string is invalid */
  428 
  429     if (my_major > rq_major
  430         || (my_major == rq_major && my_minor > rq_minor)
  431         || (my_major == rq_major && my_minor == rq_minor
  432         && my_micro > rq_micro)
  433         || (my_major == rq_major && my_minor == rq_minor
  434         && my_micro == rq_micro
  435         && strcmp(my_plvl, rq_plvl) >= 0)) {
  436         return ver;
  437     }
  438     return NULL;
  439 }