summaryrefslogtreecommitdiffstats
path: root/auth/eurephia_authplugin_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth/eurephia_authplugin_driver.c')
-rw-r--r--auth/eurephia_authplugin_driver.c194
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;
+}