/**************************************************************** * * * Copyright 2009, 2012 Fidelity Information Services, Inc * * * * This source code contains the intellectual property * * of its copyright holder(s), and is made available * * under a license. If you do not know the terms of * * the license, please stop and do not read further. * * * ****************************************************************/ #include "mdef.h" #include "gtm_string.h" #include "gtm_limits.h" /* for GTM_PATH_MAX */ #include #include #include "lv_val.h" /* needed for "fgncal.h" */ #include "fgncal.h" /* needed for COPY_DLLERR_MSG() */ #include "gtmmsg.h" #include "gtm_stdio.h" #include "gtm_stdlib.h" #include "real_len.h" #include "gtmcrypt.h" #include "iosp.h" /* for SS_NORMAL */ #include "trans_log_name.h" #ifndef GTM_DIST #define GTM_DIST "gtm_dist" #endif #define GTM_CRYPT_PLUGIN "$gtm_crypt_plugin" #define MAX_GTMCRYPT_PLUGIN_STR_LEN (SIZEOF(GTMCRYPT_LIBNAME) * 4) #define PLUGIN_DIR_NAME "plugin" GBLREF char dl_err[MAX_ERRSTR_LEN]; error_def(ERR_CRYPTDLNOOPEN); error_def(ERR_GTMDISTUNDEF); uint4 gtmcrypt_entry() { void_ptr_t handle, fptr; char_ptr_t err_str, env_ptr, libname_ptr, libpath_ptr; char *gtmcryptlib_fname[] = { GTMCRYPT_INIT_FNAME, GTMCRYPT_CLOSE_FNAME, GTMCRYPT_HASH_GEN_FNAME, GTMCRYPT_ENCRYPT_FNAME, GTMCRYPT_DECRYPT_FNAME, GTMCRYPT_GETKEY_BY_NAME, GTMCRYPT_GETKEY_BY_HASH, GTMCRYPT_STRERROR }; void **gtmcryptlib_fptr[] = { (void **)>mcrypt_init_fnptr, (void **)>mcrypt_close_fnptr, (void **)>mcrypt_hash_gen_fnptr, (void **)>mcrypt_encrypt_fnptr, (void **)>mcrypt_decrypt_fnptr, (void **)>mcrypt_getkey_by_name_fnptr, (void **)>mcrypt_getkey_by_hash_fnptr, (void **)>mcrypt_strerror_fnptr }; int findx, num_dlsyms, plugin_dir_len, save_errno; char libpath[GTM_PATH_MAX], buf[MAX_GTMCRYPT_PLUGIN_STR_LEN], plugin_dir_path[GTM_PATH_MAX]; char resolved_libpath[GTM_PATH_MAX], resolved_gtmdist[GTM_PATH_MAX]; mstr trans, env_var = {0, SIZEOF(GTM_CRYPT_PLUGIN) - 1, GTM_CRYPT_PLUGIN}; if (NULL == (env_ptr = getenv(GTM_DIST))) rts_error(VARLSTCNT(1) ERR_GTMDISTUNDEF); if (NULL == realpath(env_ptr, &resolved_gtmdist[0])) { save_errno = errno; SNPRINTF(dl_err, MAX_ERRSTR_LEN, "Failed to find symbolic link for %s. %s", env_ptr, STRERROR(save_errno)); return ERR_CRYPTDLNOOPEN; } SNPRINTF(plugin_dir_path, GTM_PATH_MAX, "%s/%s", resolved_gtmdist, PLUGIN_DIR_NAME); plugin_dir_len = STRLEN(plugin_dir_path); if ((SS_NORMAL != TRANS_LOG_NAME(&env_var, &trans, buf, SIZEOF(buf), do_sendmsg_on_log2long)) || (0 >= trans.len)) { /* Either $gtm_crypt_plugin is not defined in the environment variable OR it is set to null-string. Fall-back to * using libgtmcrypt.so */ libname_ptr = GTMCRYPT_LIBNAME; } else libname_ptr = &buf[0]; /* value of $gtm_crypt_plugin */ SNPRINTF(libpath, GTM_PATH_MAX, "%s/%s", plugin_dir_path, libname_ptr); if (NULL == realpath(&libpath[0], &resolved_libpath[0])) { save_errno = errno; SNPRINTF(dl_err, MAX_ERRSTR_LEN, "Failed to find symbolic link for %s. %s", libpath, STRERROR(save_errno)); return ERR_CRYPTDLNOOPEN; } /* Symbolic link found. dlopen resolved_libpath */ if (0 != memcmp(&resolved_libpath[0], plugin_dir_path, plugin_dir_len)) { /* resolved_path doesn't contain $gtm_dist/plugin as the prefix */ SNPRINTF(dl_err, MAX_ERRSTR_LEN, "Symbolic link for %s must be relative to %s", libpath, plugin_dir_path); return ERR_CRYPTDLNOOPEN; } handle = dlopen(&resolved_libpath[0], GTMCRYPT_LIBFLAGS); if (NULL == handle) { COPY_DLLERR_MSG(err_str, dl_err); return ERR_CRYPTDLNOOPEN; } num_dlsyms = ARRAYSIZE(gtmcryptlib_fptr); /* number of functions to be dlsym'ed */ for(findx = 0; findx < num_dlsyms; ++findx) { fptr = (void *)dlsym(handle, gtmcryptlib_fname[findx]); if (NULL == fptr) { COPY_DLLERR_MSG(err_str, dl_err); return ERR_CRYPTDLNOOPEN; } *gtmcryptlib_fptr[findx] = fptr; } return 0; }