diff options
Diffstat (limited to 'auth/eurephia_authplugin_driver.c')
-rw-r--r-- | auth/eurephia_authplugin_driver.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/auth/eurephia_authplugin_driver.c b/auth/eurephia_authplugin_driver.c new file mode 100644 index 0000000..1eb76b1 --- /dev/null +++ b/auth/eurephia_authplugin_driver.c @@ -0,0 +1,194 @@ +/* eurephia_authplugin_driver.c + * + * Copyright (C) 2013 David Sommerseth <dazo@users.sourceforge.net> + * + * 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 <http://www.gnu.org/licenses/>. + * + */ + +/** + * @file eurephia_authplugin_driver.c + * @author David Sommerseth <dazo@users.sourceforge.net> + * @date 2013-02-15 + * + * @brief Functions for preparing the plug-in pointers for the eAuthPluginCTX + */ + +#include <string.h> +#include <dlfcn.h> +#include <assert.h> + +#include <eurephia_context.h> +#include <eurephia_authplugin_driver.h> +#include <eurephia_nullsafe.h> +#include <eurephia_log.h> +#include <eurephia_getsym.h> + +/** + * 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; +} |