/* eurephia_authplugin_driver.c * * Copyright (C) 2013 David Sommerseth * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ /** * @file eurephia_authplugin_driver.c * @author David Sommerseth * @date 2013-02-15 * * @brief Functions for preparing the plug-in pointers for the eAuthPluginCTX */ #include #include #include #include #include #include #include #include /** * Opens an eurephia plug-in and retrieves a copy of the plug-in information. * NB! The returned ePluginInfo struct must be explicitly freed, as this is * a malloced memory region containing a copy of the plug-in info. * * @param eurephiaCTX* Pointer to the current eurephia context * @param dlfilename String containing the filename to the plug-in to inspect * * @return Returns a pointer to a copy of the plug-in information on success. Otherwise * NULL. If not NULL, this result must be freed by using ePluginInfoFree() */ ePluginInfoRW* ePluginInspect(eurephiaCTX * ctx, const char * dlfilename) { ePluginInfo *plginf = NULL; ePluginInfoRW *ret = NULL; void *dlhandle = NULL; ePluginInfo * (*PluginInfo)(); assert(ctx != NULL); assert(dlfilename != NULL); dlhandle = dlopen(dlfilename, RTLD_NOW); if (dlhandle == NULL) { eurephia_log(ctx, LOG_FATAL, 0, "Could not load eurephia plugin %s", dlfilename); eurephia_log(ctx, LOG_FATAL, 1, "dlopen error: %s", dlerror()); return NULL; } PluginInfo = eGetSym(ctx, dlhandle, "PluginInfo"); if (ctx->fatal_error > 0) { dlclose(dlhandle); return NULL; } plginf = PluginInfo(); /* Make a copy of the plug-in info, so we can close the plug-in */ ret = malloc_nullsafe(ctx, sizeof(ePluginInfo)+2); ret->name = strdup_nullsafe((char *) plginf->name); ret->version = strdup_nullsafe((char *) plginf->version); ret->copyright = strdup_nullsafe((char *) plginf->copyright); ret->pluginType = plginf->pluginType; ret->APIversion = plginf->APIversion; dlclose(dlhandle); return ret; } /** * Frees the memory allocated by ePluginInspect() * * @param eurephiaCTX* Pointer to the current eurephia context * @param ePluginInfo* Pointer to the ePluginInfo buffer to be freed */ void ePluginInfoFree(eurephiaCTX *ctx, ePluginInfoRW *plginf) { assert( ctx != NULL ); assert( plginf != NULL ); free_nullsafe(ctx, plginf->name); free_nullsafe(ctx, plginf->version); free_nullsafe(ctx, plginf->copyright); free_nullsafe(ctx, plginf); } /** * Helper function used by eAuthPlugin_Init(). This will look-up symbols in an * external authenticaion plug-in (.so file) which the eurephia context allows. * The available functions, based on the eurephia context, will be returned * via the eAuthPlugin struct. * * @param eurephiaCTX* Pointer to the current eurephia context * @param dlfilename* String pointer to the auth-plugin filename, used in error messages only * @param dlhandle* The dl handle returned by dlopen() for the auth-plugin to setup * * @return On success it returns a pointer to an eAuthPlugin struct which defines all available * functions in the authentication plug-in. Otherwise NULL is returned. */ eAuthPlugin * __eAuthPlugin_Setup(eurephiaCTX * ctx, const char * dlfilename, void * dlhandle) { eAuthPlugin *ret = NULL; ePluginInfo *plginfo = NULL; // Ensure we have sane contexts assert(ctx != NULL); assert(ctx->fatal_error == 0); assert(dlhandle != NULL); // Allocate memory to the plug-in function pointers, // saved in a eAuthPlugin struct ret = malloc_nullsafe(ctx, sizeof(struct __eAuthPlugin)+2); ret->PluginInfo = eGetSym(ctx, dlhandle, "PluginInfo"); ret->PluginInit = eGetSym(ctx, dlhandle, "PluginInit"); ret->PluginClose = eGetSym_optional(ctx, dlhandle, "PluginClose"); // If any of the eGetSym() triggered a fatal error, // reset the fatality mark and return with a failure code if (ctx->fatal_error > 0) { free_nullsafe(ctx, ret); ctx->fatal_error = 0; return NULL; } // Grap the API version for this plugin plginfo = ret->PluginInfo(); if (plginfo->pluginType != eptAUTH) { eurephia_log(ctx, LOG_FATAL, 0, "Plug-in %s is not an authentication plug-in", dlfilename); free_nullsafe(ctx, ret); return NULL; } // Only allow the following functions if the eurephia context is // based on a admin interface or the openvpn authentication plug-in. if ((ctx->context_type == ECTX_PLUGIN_AUTH) || (ctx->context_type == ECTX_ADMIN_CONSOLE) || (ctx->context_type == ECTX_ADMIN_WEB) ) { switch( plginfo->APIversion ) { case 1: ret->AuthenticateUser = eGetSym(ctx, dlhandle, "AuthenticateUser"); break; default: eurephia_log(ctx, LOG_CRIT, 0, "Invalid API version reported " "in %s: APIversion=%i. Plug-in disabled", dlfilename, plginfo->APIversion); memset(ret, 0, sizeof(eAuthPlugin)); free_nullsafe(ctx, ret); return NULL; } } // Only allow the following functions if we're in a // administration context if ((ctx->context_type == ECTX_ADMIN_CONSOLE) || (ctx->context_type == ECTX_ADMIN_WEB)) { switch( plginfo->APIversion ) { case 1: ret->ChangePassword = eGetSym_optional(ctx, dlhandle, "ChangePassword"); break; default: eurephia_log(ctx, LOG_CRIT, 0, "Invalid API version reported " "in %s: APIversion=%i. Plug-in disabled", dlfilename, plginfo->APIversion); memset(ret, 0, sizeof(eAuthPlugin)); free_nullsafe(ctx, ret); return NULL; } } // Return a struct containing the plug-in functions return ret; }