summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2013-05-28 16:08:38 +0200
committerDavid Sommerseth <dazo@users.sourceforge.net>2013-05-28 16:08:38 +0200
commitfc4958f6e957acd72e3ec6f9a546811cdf70f4d3 (patch)
tree8bf6d050baf35c1603f64e70bedc08c2d424924d
parentbfe23dd4341de02e7981fbdbd87550cdc19d6830 (diff)
parentd4383e6b96e36120669cc6de2f2cec49aeee90f4 (diff)
downloadeurephia-fc4958f6e957acd72e3ec6f9a546811cdf70f4d3.tar.gz
eurephia-fc4958f6e957acd72e3ec6f9a546811cdf70f4d3.tar.xz
eurephia-fc4958f6e957acd72e3ec6f9a546811cdf70f4d3.zip
Merge auth-plugin work
This implements a authentication plug-in framework which can be used to do username/password authentication against another backend per user/certificate. Conflicts: database/eurephiadb.c Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
-rw-r--r--CMakeLists.txt2
-rw-r--r--auth/dummy/CMakeLists.txt35
-rw-r--r--auth/dummy/dummy-auth.c124
-rw-r--r--auth/eurephia_authplugin.c228
-rw-r--r--auth/eurephia_authplugin_context.h54
-rw-r--r--auth/eurephia_authplugin_driver.c194
-rw-r--r--auth/eurephia_authplugin_driver.h187
-rw-r--r--auth/eurephia_authplugin_func.h74
-rw-r--r--common/CMakeLists.txt4
-rw-r--r--common/eurephia_context.h5
-rw-r--r--common/eurephia_getsym.c26
-rw-r--r--common/eurephia_getsym.h1
-rw-r--r--database/eurephiadb.c24
-rw-r--r--database/eurephiadb.h3
-rw-r--r--database/eurephiadb_driver.h79
-rw-r--r--database/eurephiadb_mapping.c75
-rw-r--r--database/eurephiadb_mapping.h99
-rw-r--r--database/sqlite/CMakeLists.txt7
-rw-r--r--database/sqlite/administration/plugins.c344
-rw-r--r--database/sqlite/edb-sqlite.c135
-rw-r--r--database/sqlite/fieldmapping.h12
-rw-r--r--database/sqlite/sql-schema-delta-3.sql38
-rw-r--r--database/sqlite/sql-schema.sql15
-rw-r--r--database/sqlite/sqlite.c1
-rw-r--r--eurephiadm/CMakeLists.txt6
-rw-r--r--eurephiadm/client_context.c2
-rw-r--r--eurephiadm/commands.h6
-rw-r--r--eurephiadm/commands/plugins.c462
-rw-r--r--man/eurephia-variables.78
-rw-r--r--plugin/CMakeLists.txt6
-rw-r--r--plugin/eurephia.c135
-rw-r--r--utils/CMakeLists.txt4
32 files changed, 2318 insertions, 77 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d28dfa8..e516767 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -181,7 +181,7 @@ SET_PROPERTY(TARGET common PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/common
# Start the building. First build the common library, and then the requested eurephia modules
IF(DATABASE OR PLUGIN OR FIREWALL OR EUREPHIADM)
- SUBDIRS(common ${subdirs})
+ SUBDIRS(common auth/dummy ${subdirs})
ENDIF(DATABASE OR PLUGIN OR FIREWALL OR EUREPHIADM)
# Compile Doxygen docs at the end if requested
diff --git a/auth/dummy/CMakeLists.txt b/auth/dummy/CMakeLists.txt
new file mode 100644
index 0000000..394215a
--- /dev/null
+++ b/auth/dummy/CMakeLists.txt
@@ -0,0 +1,35 @@
+# cmake rules for eurephia - dummy-auth plug-in
+#
+# This module is only for testing purpose.
+# DO NO USE THIS PLUG-IN IN A PRODUCTION ENVIRONMENT
+#
+# GPLv2 only - Copyright (C) 2008 - 2012
+# 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; version 2
+# of the License.
+#
+# 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+PROJECT(eurephiaUnitTest C)
+cmake_minimum_required(VERSION 2.6)
+
+# Compiler settigns
+INCLUDE_DIRECTORIES(. ../../common .. ../../database)
+
+ADD_LIBRARY(dummy-auth SHARED
+ dummy-auth.c
+)
+TARGET_LINK_LIBRARIES(dummy-auth common)
+SET_TARGET_PROPERTIES(dummy-auth PROPERTIES COMPILE_FLAGS -fPIC)
+SET_TARGET_PROPERTIES(dummy-auth PROPERTIES OUTPUT_NAME dummy-auth PREFIX "")
+
diff --git a/auth/dummy/dummy-auth.c b/auth/dummy/dummy-auth.c
new file mode 100644
index 0000000..5425d50
--- /dev/null
+++ b/auth/dummy/dummy-auth.c
@@ -0,0 +1,124 @@
+/* dummy-auth.c -- Stupid dummy authentication - ONLY FOR TESTING PURPOSES
+ *
+ * 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 dummy-auth.c
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2013-02-15
+ *
+ * @brief Simple and stupid dummy authentication. ONLY FOR TESTING PURPOSES
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <eurephia_nullsafe.h>
+#include <eurephia_context.h>
+#include <eurephia_log.h>
+#include <eurephia_authplugin_driver.h>
+
+static ePluginInfo pluginfo = { .name = "Dummy-Authentication plug-in",
+ .version = "1.0",
+ .copyright = "2013 (C) David Sommerseth <dazo@users.sourceforge.net>",
+ .pluginType = eptAUTH,
+ .APIversion = 1 };
+
+
+/**
+ * @copydoc PluginInfo()
+ */
+ePluginInfo * PluginInfo()
+{
+ return &pluginfo;
+}
+
+/**
+ * @copydoc PluginInit()
+ */
+int PluginInit(eurephiaCTX *ctx, const char *args)
+{
+ eurephia_log(ctx, LOG_INFO, 0, "Dummy auth initialised: %s", args);
+ eurephia_log(ctx, LOG_WARNING, 0, "DO NOT USE dummy-auth IN PRODUCTION");
+ return 1;
+}
+
+
+/**
+ * @copydoc PluginClose()
+ */
+void PluginClose(eurephiaCTX *ctx)
+{
+ eurephia_log(ctx, LOG_INFO, 0, "Closing Dummy auth");
+}
+
+
+/**
+ * Generic dummy authentication used by both AuthenticateUser() and
+ * ChangePassword(). This particular implementation is not safe to use in
+ * a production environment, as it only considers hard coded passwords
+ * for testing purposes.
+ *
+ * @param eurephiCTX* Pointer to the global eurephia context
+ * @param username* Char pointer to a buffer containing the username
+ * @param passwd* Char pointer to a buffer containing the password in
+ * clear text
+ *
+ * @return Returns a pointer to an eAuthResult struct with the authentication
+ * result. On generic system failures, it may return NULL.
+ */
+eAuthResult * _dummy_auth(eurephiaCTX *ctx, const char *username, const char *passwd)
+{
+ eAuthResult *res = NULL;
+
+ res = malloc_nullsafe(ctx, sizeof(eAuthResult)+2);
+ if( strcmp(passwd, "correct") == 0) {
+ res->status = eAUTH_SUCCESS;
+ res->msg = strdup("User authenticated successfully");
+ } else if( strcmp(passwd, "wrong") == 0){
+ res->status = eAUTH_FAILED;
+ res->msg = strdup("User authentication forced to fail");
+ } else {
+ res->status = eAUTH_PLGERROR;
+ res->msg = strdup("Authentication plug-in failed");
+ }
+ return res;
+}
+
+
+/**
+ * @copydoc AuthenticateUser()
+ */
+eAuthResult * AuthenticateUser(eurephiaCTX *ctx, const char *username, const char *passwd)
+{
+ eurephia_log(ctx, LOG_INFO, 0, "dummy-auth:AuthenticateUser('%s', '%s')",
+ username, passwd);
+ return _dummy_auth(ctx, username, passwd);
+}
+
+
+/**
+ * @copydoc ChangePassword()
+ */
+eAuthResult * ChangePassword(eurephiaCTX *ctx, const char *username,
+ const char *oldpass, const char *newpass)
+{
+ eurephia_log(ctx, LOG_INFO, 0, "dummy-auth:ChangePassword('%s', '%s', '%s')",
+ username, oldpass, newpass);
+ return _dummy_auth(ctx, username, newpass);
+}
+
diff --git a/auth/eurephia_authplugin.c b/auth/eurephia_authplugin.c
new file mode 100644
index 0000000..5646209
--- /dev/null
+++ b/auth/eurephia_authplugin.c
@@ -0,0 +1,228 @@
+/* eurephia_authplugin.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.c
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2013-02-15
+ *
+ * @brief Authentication plug-in framework for eurephia
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <assert.h>
+
+#define EUREPHIA_AUTHPLUGIN_C_
+#define EUREPHIA_CONTEXT_H_
+typedef struct __eurephiaCTX eurephiaCTX;
+
+#include <eurephia_authplugin_driver.h>
+#include <eurephia_authplugin_context.h>
+#include <eurephia_nullsafe.h>
+#include <eurephia_values_struct.h>
+#include <eurephia_values.h>
+#include <eurephia_log.h>
+#include <eurephiadb_driver.h>
+#include <eurephia_getsym.h>
+
+eAuthPlugin * __eAuthPlugin_Setup(eurephiaCTX * ctx, const char * dlfilename, void * dlhandle);
+
+struct __PluginDataSplit {
+ const char *dsofile;
+ const char *configstr;
+};
+
+/**
+ * Splits the plug-in data from the database into a more easily managable
+ * struct. This struct will only use pointers to the input string (dbstr)
+ * And the input string will be slightly modified.
+ *
+ * The format of the input data is:
+ * [<DSO filename>]<Configuration string>
+ *
+ * @param ret* The parsed result will be saved into in the provided struct
+ * @param dbstr* The string returned by the database, containing plug-in data
+ *
+ * @return Data is returned via the ret* pointer
+ */
+void __split_plugin_data_str(struct __PluginDataSplit *ret, char *dbstr)
+{
+ char *ptr = NULL;
+
+ assert(ret != NULL);
+ assert(dbstr != NULL);
+
+ ret->dsofile = NULL;
+ ret->configstr = NULL;
+
+ /* The input string must start with '[' */
+ if (dbstr[0] != '[') {
+ return;
+ }
+
+ /* Locate the ']' part. This will be replaced by a NULL terminator */
+ ptr = strpbrk(dbstr, "]");
+ if (ptr == NULL) {
+ /* If not found, abort */
+ return;
+ }
+
+ dbstr[0] = 0; /* NULL terminate it on purpose */
+ ret->dsofile = dbstr+1;
+ *ptr = 0; /* NULL terminate the ']' place */
+ ret->configstr = ptr+1;
+}
+
+
+eAuthPluginCTX * eAuthPlugin_Init(eurephiaCTX * ctx)
+{
+ eurephiaVALUES *plgs = NULL, *plgptr;
+ eAuthPluginCTX *apctx = NULL, *apctxhead = NULL;
+ struct __PluginDataSplit plgdata;
+
+ // Query the database for authentication plugins
+ plgs = eDBget_plugins(ctx, "auth");
+ if (plgs == NULL) {
+ return NULL;
+ }
+
+ // Parse the result, load plugins and save them into
+ // separate auth plug-in contexts
+ for (plgptr = plgs; plgptr != NULL; plgptr = plgptr->next) {
+ // Ensure that we have value plug-in information
+ if (plgptr == NULL || plgptr->key == NULL || plgptr->val == NULL) {
+ continue;
+ }
+
+ __split_plugin_data_str(&plgdata, plgptr->val);
+
+ // Create a plug-in context
+ apctx = malloc_nullsafe(ctx, sizeof(eAuthPluginCTX)+2);
+
+ // Save some metadata about this plugin
+ apctx->filename = strdup(plgdata.dsofile);
+ apctx->plgid = atoi_nullsafe(plgptr->key);
+ apctx->next = NULL;
+ // Open the plugin
+ apctx->dlhandle = dlopen(apctx->filename, RTLD_NOW);
+ if (apctx->dlhandle != NULL) {
+ int success = 0;
+
+ // If we got a handle to the plug-in, it up
+ apctx->plugin = __eAuthPlugin_Setup(ctx, apctx->filename, apctx->dlhandle);
+ if (apctx->plugin != NULL) {
+ ePluginInfo *plginfo = apctx->plugin->PluginInfo();
+
+ eurephia_log(ctx, LOG_INFO, 1,
+ "Loaded eurephia %s plugin: %s (v%s) %s",
+ ePluginTypeString(plginfo),
+ plginfo->name, plginfo->version, plginfo->copyright);
+
+ // Initialise the plug-in
+ success = apctx->plugin->PluginInit(ctx, plgdata.configstr);
+ }
+
+ if (success == 1) {
+ // On success, add this plug-in to the context chain
+ if( apctxhead != NULL ) {
+ apctx->next = apctxhead;
+ }
+ apctxhead = apctx;
+ } else {
+ // On failure to setup the plug-in, disable it
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Failed to initialse eurephia plugin %s. "
+ "Plug-in disabled.",
+ apctx->filename);
+ free_nullsafe(ctx, apctx->filename);
+ dlclose(apctx->dlhandle);
+ apctx->plgid = 0;
+ apctx->next = NULL;
+ free(apctx);
+ }
+ } else {
+ // On failure to load the plug-in ... Report error and ignore plug-in.
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not load eurephia plugin %s",
+ apctx->filename);
+ eurephia_log(ctx, LOG_FATAL, 1, "dlopen error: %s", dlerror());
+ free_nullsafe(ctx, apctx->filename);
+ apctx->plgid = 0;
+ apctx->next = NULL;
+ free(apctx);
+ }
+ }
+ eFree_values(ctx, plgs);
+
+ // Return the plug-in context chain
+ return apctxhead;
+}
+
+
+eAuthPlugin * eAuthPlugin_Get(eAuthPluginCTX *apctx, const int plgid)
+{
+ eAuthPluginCTX *ptr = apctx;
+
+ if (apctx == NULL) {
+ return NULL;
+ }
+
+ while (ptr) {
+ // Return a pointer to the authentication plug-in functions
+ // if found
+ if (ptr->plgid == plgid) {
+ return ptr->plugin;
+ }
+ ptr = ptr->next;
+ }
+ return NULL;
+}
+
+
+void _eAuthPlugin_Close(eurephiaCTX *ctx, eAuthPluginCTX *apctx)
+{
+ eAuthPluginCTX *ptr = apctx, *next = NULL;
+
+ while (ptr) {
+ // Save a pointe to the next plug-in context
+ next = ptr->next;
+ ptr->next = NULL;
+
+ if (ptr->plugin->PluginClose) {
+ ptr->plugin->PluginClose(ctx);
+ }
+
+ // Close the plug-in handle
+ if (ptr->dlhandle) {
+ dlclose(ptr->dlhandle);
+ }
+
+ // Clean up memory allocated by the plug-in context
+ free_nullsafe(ctx, ptr->filename);
+ ptr->plgid = 0;
+ free_nullsafe(ctx, ptr->plugin);
+ free_nullsafe(ctx, ptr);
+
+ // Go to next plug-in context
+ ptr = next;
+ }
+}
+
diff --git a/auth/eurephia_authplugin_context.h b/auth/eurephia_authplugin_context.h
new file mode 100644
index 0000000..cc73129
--- /dev/null
+++ b/auth/eurephia_authplugin_context.h
@@ -0,0 +1,54 @@
+/* eurephia_authplugin_context.h
+ *
+ * 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_context.h
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2013-02-15
+ *
+ * @brief eurephia authentication plug-in context definition
+ */
+
+#ifndef EUREPHIA_AUTHPLUGIN_CONTEXT_H_
+#define EUREPHIA_AUTHPLUGIN_CONTEXT_H_
+
+#ifdef EUREPHIA_AUTHPLUGIN_C_
+/**
+ * Authentication plug-in context.
+ * Contains an overview of all loaded authentication plug-ins
+ *
+ * This struct is only visible for eurephia_authplugin.c, to
+ * avoid nesting troubles when eurephiaCTX needs declared eAuthPlugin
+ * which again needs eurephiaCTX to already be defined.
+ *
+ */
+typedef struct __eAuthPluginCTX {
+ char *filename; /**< Filename of the plug-in */
+ void *dlhandle; /**< Handle to plug-in returned by dlopen() */
+ unsigned int plgid; /**< Name of the plug-in, retrieved from the database */
+ eAuthPlugin *plugin; /**< Access to the plug-in funcions */
+
+ struct __eAuthPluginCTX *next; /**< Pointer to the next auth plug-in */
+} eAuthPluginCTX;
+#else
+typedef struct __eAuthPluginCTX eAuthPluginCTX;
+#endif /* EUREPHIA_AUTHPLUGIN_C_ */
+
+
+#endif /* EUREPHIA_AUTHPLUGIN_CONTEXT_H_ */
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;
+}
diff --git a/auth/eurephia_authplugin_driver.h b/auth/eurephia_authplugin_driver.h
new file mode 100644
index 0000000..97197ed
--- /dev/null
+++ b/auth/eurephia_authplugin_driver.h
@@ -0,0 +1,187 @@
+/* eurephia_authplugin_driver.h
+ *
+ * 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.h
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2013-02-15
+ *
+ * @brief Authentication plug-in framework for eurephia
+ */
+
+#ifndef EUREPHIA_AUTHPLUGIN_DRIVER_H_
+#define EUREPHIA_AUTHPLUGIN_DRIVER_H_
+
+/**
+ * Supported plug-in types
+ */
+typedef enum {
+ eptAUTH /**< Used by authentication plug-ins */
+} ePluginType;
+
+/**
+ * Translation table for ePluginType into a readable string
+ * This table must match the ePluginType enumeration.
+ */
+static const char *___ePluginTypeString[] = {
+ "authentication", /* eptAUTH */
+ NULL
+};
+
+static const char *___ePluginTypeShortString[] = {
+ "auth", /* eptAUTH */
+ NULL
+};
+
+
+/**
+ * Struct providing plug-in information
+ */
+typedef const struct __ePluginInfo {
+ const char *name; /**< Readable plug-in name */
+ const char *version; /**< Plug-in version string */
+ const char *copyright; /**< Copyright of the plug-in */
+ const ePluginType pluginType; /**< Plug-in type */
+ const int APIversion; /**< Plug-in API level support */
+} ePluginInfo;
+
+
+/**
+ * Struct providing plug-in information, a "read-write"
+ * version of ePluginInfo, used by ePluginInspect()
+ */
+typedef struct __ePluginInfoRW {
+ char *name; /**< Readable plug-in name */
+ char *version; /**< Plug-in version string */
+ char *copyright; /**< Copyright of the plug-in */
+ ePluginType pluginType; /**< Plug-in type */
+ int APIversion; /**< Plug-in API level support */
+} ePluginInfoRW;
+
+
+/**
+ * Simple function for getting a readable string of the plug-in type.
+ *
+ * @return Returns a char pointer to a static const buffer containing the
+ * plug-in type.
+ */
+static inline const char * ePluginTypeString(ePluginInfo *plginf)
+{
+ return ___ePluginTypeString[plginf->pluginType];
+}
+
+/**
+ * Simple function for getting a readable short string of the plug-in type.
+ *
+ * @return Returns a char pointer to a static const buffer containing the
+ * plug-in type.
+ */
+static inline const char * ePluginTypeShortString(ePluginInfo *plginf)
+{
+ return ___ePluginTypeShortString[plginf->pluginType];
+}
+
+
+/**
+ * Authentication result codes
+ */
+typedef enum { eAUTH_FAILED, /**< Authentication failed */
+ eAUTH_SUCCESS, /**< Authentication successful */
+ eAUTH_PLGERROR /**< An error occured in the auth plug-in */
+} eAuthResStatus;
+
+/**
+ * Result type for authentication plug-ins
+ */
+typedef struct __eAuthResult {
+ eAuthResStatus status; /**< Overall status of the operation */
+ char *msg; /**< Optinal descriptive information */
+} eAuthResult;
+
+
+/**
+ * Authentication plug-in API
+ */
+typedef struct __eAuthPlugin {
+ /**
+ * Returns information about the authentication plug-in. All
+ * authentication plug-ins must provide this function.
+ *
+ * @return Will always return a pointer to a const struct containing
+ * the plug-in information.
+ */
+ ePluginInfo * (*PluginInfo)();
+
+ /**
+ * Initialisation function for the plug-in.
+ *
+ * @param eurephiaCTX* Pointer to the current eurephia context
+ * @param args String containing the initialisation data
+ *
+ * @return Returns 1 on success, otherwise 0
+ */
+ int (*PluginInit)(eurephiaCTX *ctx, const char *args);
+
+
+ /**
+ * Function for "closing" for the plug-in.
+ *
+ * @param eurephiaCTX* Pointer to the current eurephia context
+ *
+ */
+ void (*PluginClose)(eurephiaCTX *ctx);
+
+
+ /**
+ * Mandatory auth plug-in function. Authenticates a user account based
+ * on the given username and password.
+ *
+ * @param eurephiaCTX* Pointer to the current eurephia context
+ * @param username* String pointer to the username for the authentication
+ * @param password* String pointer to the password for the authentication
+ *
+ * @returns On success it returns a pointer to an eAuthResult struct, which
+ * contains further information on the success of the authentication.
+ * On system failure, NULL is returned.
+ */
+ eAuthResult * (*AuthenticateUser)(eurephiaCTX *ctx,
+ const char *username,
+ const char *password);
+
+ /**
+ * ChangePassword() is only enabled if allowed by config and supported
+ * by (optionally) by the plug-in. The eurephia context must be in
+ * an admin mode for this to be enabled.
+ *
+ * @param eurephiaCTX* Pointer to the current eurephia context
+ * @param username* String pointer to the username account for the password change
+ * @param oldpwd* String pointer to the old password, for authentication
+ * @param newpwd* String pointer to the new password
+ *
+ * @returns On success it returns a pointer to an eAuthResult struct, which
+ * contains further information on the success of the authentication.
+ * On system failure, NULL is returned.
+ */
+ eAuthResult * (*ChangePassword)(eurephiaCTX *ctx,
+ const char *username,
+ const char *oldpwd,
+ const char *newpwd);
+} eAuthPlugin;
+
+#endif /* EUREPHIA_AUTHPLUGIN_DRIVER_H_ */
diff --git a/auth/eurephia_authplugin_func.h b/auth/eurephia_authplugin_func.h
new file mode 100644
index 0000000..372f262
--- /dev/null
+++ b/auth/eurephia_authplugin_func.h
@@ -0,0 +1,74 @@
+/* eurephia_authplugin_func.h
+ *
+ * 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_func.h
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2013-02-15
+ *
+ * @brief Authentication plug-in framework for eurephia
+ */
+
+#ifndef EUREPHIA_AUTHPLUGIN_FUNC_H_
+#define EUREPHIA_AUTHPLUGIN_FUNC_H_
+
+#if !defined(EUREPHIA_AUTHPLUGIN_CONTEXT_H_) && !defined(EUREPHIA_AUTHPLUGIN_DRIVER_H_)
+#error eurephia_authplugin_func.h depends on eurephia_authplugin_contxt.h or eurephia_authplugin_driver.h
+#endif
+
+#ifdef EUREPHIA_AUTHPLUGIN_CONTEXT_H_
+/**
+ * Initialises the eAuthPluginCTX and loads all configured auth plug-ins
+ *
+ * @param eurephiaCTX* Pointer to the global eurephiaCTX. A database driver
+ * must already be initialised
+ *
+ * @return Returns a pointer to a eAuthPluginCTX on success, otherwise NULL.
+ */
+eAuthPluginCTX * eAuthPlugin_Init(eurephiaCTX * ctx);
+
+/**
+ * Closes and frees up the memory used by eAuthPluginCTX
+ *
+ * @param eAuthPluginCTX* Pointer to the eAuthPluginCTX to free
+ *
+ * @return Returns 1 on success, otherwise 0
+ */
+void _eAuthPlugin_Close(eurephiaCTX *ctx, eAuthPluginCTX *apctx);
+#define eAuthPlugin_Close(c, apc) { _eAuthPlugin_Close(c, apc); apc = NULL; };
+#endif /* EUREPHIA_AUTHPLUGIN_CONTEXT_H_ */
+
+
+#ifdef EUREPHIA_AUTHPLUGIN_DRIVER_H_
+/**
+ * Retrieves a plug-in API based on the plug-in name.
+ *
+ * @param eAuthPluginCTX* Pointer to the authentication plugin context
+ * @param char* Name of the auth-plugin to look up
+ *
+ * @return Returns a pointer to the plug-in API on success, otherwise NULL
+ */
+eAuthPlugin * eAuthPlugin_Get(eAuthPluginCTX *apctx, const int plgid);
+
+ePluginInfoRW * ePluginInspect(eurephiaCTX * ctx, const char * dlfilename);
+void ePluginInfoFree(eurephiaCTX *ctx, ePluginInfoRW *plginf);
+
+#endif /* EUREPHIA_AUTHPLUGIN_DRIVER_H_ */
+
+#endif /* EUREPHIA_AUTHPLUGIN_FUNC_H */
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 3a9ff45..ad4c3c7 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -1,6 +1,6 @@
# cmake rules for eurephia - common static library
#
-# GPLv2 only - Copyright (C) 2008 - 2012
+# GPLv2 only - Copyright (C) 2008 - 2013
# David Sommerseth <dazo@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or
@@ -21,7 +21,7 @@ PROJECT(eurephiaCOMMON C)
cmake_minimum_required(VERSION 2.6)
# Compiler settigns
-INCLUDE_DIRECTORIES(. ../database)
+INCLUDE_DIRECTORIES(. ../database ../auth)
# Only compile these files if we have libxml2
SET(add_xml_code "")
diff --git a/common/eurephia_context.h b/common/eurephia_context.h
index 845850b..b21dde8 100644
--- a/common/eurephia_context.h
+++ b/common/eurephia_context.h
@@ -34,6 +34,8 @@
#include <stdio.h>
#include <eurephiadb_struct.h>
#include <eurephia_log_struct.h>
+#include <eurephia_authplugin_context.h>
+
/**
* eurephia context types
*/
@@ -52,6 +54,7 @@ typedef enum OVPN_tunnelType_e { tuntype_UNKN, /**< Unknwown */
tuntype_TUN /**< OpenVPN is used with --dev tun */
} OVPN_tunnelType;
+
/**
* main structure for the eurephia module context
* - the same context structure is used for all OpenVPN sessions
@@ -66,6 +69,8 @@ typedef struct {
#else
void *fwcfg; /**< Dummy pointer, if the firewall API is not enabled */
#endif
+ unsigned int nointernalauth; /**< If set, don't use internal eurephia authentication */
+ eAuthPluginCTX *authplugs; /**< Authentication plug-in contexts. May be NULL */
char *server_salt; /**< The in-memory password salt, used for the password cache */
eurephiaLOG *log; /**< Log context, used by eurephia_log() */
int fatal_error; /**< If this flag is set, the execution should stop immediately */
diff --git a/common/eurephia_getsym.c b/common/eurephia_getsym.c
index 1b9a63e..9460c3a 100644
--- a/common/eurephia_getsym.c
+++ b/common/eurephia_getsym.c
@@ -43,20 +43,36 @@
*
* @return Returns a pointer to the function if it was found, otherwise NULL is returned.
*/
-void *eGetSym(eurephiaCTX *ctx, void *dlh, const char *symnam)
+void *eGetSym_optional(eurephiaCTX *ctx, void *dlh, const char *symnam)
{
- void *func = NULL;
-
if( ctx->fatal_error > 0 ) {
return NULL;
}
DEBUG(ctx, 30, "Locating driver function '%s'", symnam);
- func = dlsym(dlh, symnam);
+ return dlsym(dlh, symnam);
+}
+
+
+/**
+ * Similar to @eGetSym_optional(), but will trigger a panic error if symnam isn't found.
+ *
+ * @param ctx eurephiaCTX
+ * @param dlh Handler which dlopen() returned
+ * @param symnam Name of the function to find
+ *
+ * @return Returns a pointer to the function if it was found, otherwise NULL is returned.
+ */
+void *eGetSym(eurephiaCTX *ctx, void *dlh, const char *symnam) {
+ void *func = NULL;
+
+ if( ctx->fatal_error > 0 ) {
+ return NULL;
+ }
+ func = eGetSym_optional(ctx, dlh, symnam);
if( func == NULL ) {
eurephia_log(ctx, LOG_PANIC, 0, "Could not find needed '%s' function in driver", symnam);
ctx->fatal_error = 1;
}
return func;
}
-
diff --git a/common/eurephia_getsym.h b/common/eurephia_getsym.h
index 8ca4bc3..73c8aa0 100644
--- a/common/eurephia_getsym.h
+++ b/common/eurephia_getsym.h
@@ -31,6 +31,7 @@
#ifndef EUREPHIA_GETSYM_H_
#define EUREPHIA_GETSYM_H_
+void *eGetSym_optional(eurephiaCTX *ctx, void *dlh, const char *symnam);
void *eGetSym(eurephiaCTX *ctx, void *dlh, const char *symnam);
#endif /* !EUREPHIA_GETSYM_H_ */
diff --git a/database/eurephiadb.c b/database/eurephiadb.c
index 186cf3f..3b1c751 100644
--- a/database/eurephiadb.c
+++ b/database/eurephiadb.c
@@ -1,6 +1,6 @@
/* eurephiadb.c -- Loads and initialises the database driver
*
- * GPLv2 only - Copyright (C) 2008 - 2012
+ * GPLv2 only - Copyright (C) 2008 - 2013
* David Sommerseth <dazo@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or
@@ -29,6 +29,7 @@
*/
#include <stdio.h>
+#include <string.h>
#include <dlfcn.h>
#include "eurephia_nullsafe.h"
@@ -117,6 +118,9 @@ int eDBlink_init(eurephiaCTX *ctx, const char *dbdriver, const int minver)
case 4:
eDBregister_login2 = eGetSym(ctx, ctx->eurephia_driver, "eDBregister_login2");
eDBget_accessprofile = eGetSym(ctx, ctx->eurephia_driver, "eDBget_accessprofile");
+ eDBauth_GetAuthMethod = eGetSym(ctx, ctx->eurephia_driver, "eDBauth_GetAuthMethod");
+ eDBget_plugins = eGetSym(ctx, ctx->eurephia_driver, "eDBget_plugins");
+ eDBadminPlugins = eGetSym(ctx, ctx->eurephia_driver, "eDBadminPlugins");
case 3:
eDBregister_vpnclientaddr = eGetSym(ctx, ctx->eurephia_driver, "eDBregister_vpnclientaddr");
@@ -181,3 +185,21 @@ int eDBlink_init(eurephiaCTX *ctx, const char *dbdriver, const int minver)
}
return 1;
}
+
+
+/**
+ * Frees the memory allocated by the eDBauth_GetAuthMethod() function
+ *
+ * @param eurephiaCTX* Pointer to the global eurephia context
+ * @param eDBauthMethodResult* Pointer to the result to be freed
+ *
+ */
+void eDBauth_FreeAuthMethodResult(eurephiaCTX *ctx, eDBauthMethodResult *res)
+{
+ if( res == NULL ) {
+ return;
+ }
+ free_nullsafe(ctx, res->username);
+ memset(res, 0, sizeof(eDBauthMethodResult));
+ free_nullsafe(ctx, res);
+}
diff --git a/database/eurephiadb.h b/database/eurephiadb.h
index e8c7e84..ea59ece 100644
--- a/database/eurephiadb.h
+++ b/database/eurephiadb.h
@@ -1,6 +1,6 @@
/* eurephiadb.h -- Database driver setup
*
- * GPLv2 only - Copyright (C) 2008 - 2012
+ * GPLv2 only - Copyright (C) 2008 - 2013
* David Sommerseth <dazo@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or
@@ -38,4 +38,5 @@
int eDBlink_init(eurephiaCTX *, const char *, const int);
int eDBlink_close(eurephiaCTX *);
+void eDBauth_FreeAuthMethodResult(eurephiaCTX *, eDBauthMethodResult *);
#endif
diff --git a/database/eurephiadb_driver.h b/database/eurephiadb_driver.h
index c6785f3..b7154ea 100644
--- a/database/eurephiadb_driver.h
+++ b/database/eurephiadb_driver.h
@@ -1,6 +1,6 @@
/* eurephiadb_driver.h -- API provided by the database driver
*
- * GPLv2 only - Copyright (C) 2008 - 2012
+ * GPLv2 only - Copyright (C) 2008 - 2013
* David Sommerseth <dazo@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or
@@ -54,6 +54,27 @@
#define USERINFO_blacklist 0x10 /**< flag for extracting information from blacklist log */
/**
+ * Defines supported authentication methods or account restrictions
+ */
+typedef enum { eAM_UNDEF, /**< Unknown/undefined/unsupported method */
+ eAM_BLACKLISTED, /**< Account has been blacklisted, no auth allowed */
+ eAM_INACTIVE, /**< Account is not active, no auth allowed */
+ eAM_INTERNDB, /**< Use the eurephia database for password authentication */
+ eAM_PLUGIN /**< Use an auth plug-in for password authentication */
+} eDBauthMethod;
+
+/**
+ * Result structure from eDBauth_GetAuthMethod()
+ */
+typedef struct __eDBauthMethodResult {
+ eDBauthMethod method; /**< Authentication method */
+ char *username; /**< Username to use with external methods */
+ unsigned int authplugid; /**< Authentication plug-in ID for external methods */
+ int uicid; /**< User account/certificate link ID */
+} eDBauthMethodResult;
+
+
+/**
* Mandatory function. Retrieves driver version information
*
* @return Returns string (const char *) containing driver version information.
@@ -114,6 +135,21 @@ int EUREPHIA_DRIVERAPI_FUNC(eDBauth_TLS)(eurephiaCTX *ctx, const char *org, cons
const char *digest, const unsigned int depth);
/**
+ * Retrieves authentication method for a specific user name and certificate ID
+ *
+ * @version API version level 1
+ * @param ctx eurephiaCTX
+ * @param certid certificate ID to the user being authenticated
+ * @param username username to be authenticated
+ *
+ * @return Returns a pointer to a eDBauthMethodResult struct which defines how
+ * to authenticate this user. On system failure, NULL is returned.
+ */
+eDBauthMethodResult * EUREPHIA_DRIVERAPI_FUNC(eDBauth_GetAuthMethod)(eurephiaCTX *ctx,
+ const int certid,
+ const char *username);
+
+/**
* Authenticates a client against the database, with users certificate ID, username and password.
*
* @version API version level 1
@@ -318,6 +354,17 @@ int EUREPHIA_DRIVERAPI_FUNC(eDBget_accessprofile) (eurephiaCTX *ctx, const int u
*/
eurephiaVALUES * EUREPHIA_DRIVERAPI_FUNC(eDBget_blacklisted_ip)(eurephiaCTX *ctx);
+/**
+ * Retrieve a list of additional configured eurephia plug-ins of a certain plug-in type
+ *
+ * @version API version level 4
+ * @param ctx eurephiaCTX
+ * @param plgtype Plug-in category type (string value, null terminated)
+ *
+ * @return Returns an eurephiaVALUES chain with all plug-ins configured, otherwise NULL is returned
+ */
+eurephiaVALUES * EUREPHIA_DRIVERAPI_FUNC(eDBget_plugins)(eurephiaCTX *ctx, const char *plgtype);
+
/* The following functions is also declared in eurephia_session_values.c - for local internal usage. */
/**
* Retrieve a unique session key based on a session seed.
@@ -697,6 +744,36 @@ xmlDoc * EUREPHIA_DRIVERAPI_FUNC(eDBadminFirewallProfiles)(eurephiaCTX *ctx, xml
/**
+ * Query or modify the eurephia plug-ins setup.
+ *
+ * @version API version level 4
+ * @param ctx eurephiaCTX
+ * @param xmlqry XML document with the operation and information.
+ *
+ * The XML format skeleton
+ * @code
+ * <eurephia format="1">
+ * <plugins mode="{search|register|unregister|modify}"
+ * [plugin-id="{ID}"] [plugin-dso="{FILENAME}]">
+ * <fieldMapping table="plugins">
+ * <{field name}>{value}</{field name}>
+ * </fieldMapping>
+ * </plugins>
+ * </eurephia>
+ * @endcode
+ * It can be several field name tags to narrow the search even more.
+ * For the register and unregister mode, either the plugin or plugin-id field name tag
+ * must be present. For modify mode one of the plugin-id or plugin-dso attributes
+ * must be present.
+ *
+ * @return Returns a valid XML document with the result on success, otherwise either
+ * NULL or an XML error document is returned.
+ * @see eurephiaXML_CreateDoc(), eurephiaXML_getRoot()
+ */
+xmlDoc * EUREPHIA_DRIVERAPI_FUNC(eDBadminPlugins)(eurephiaCTX *ctx, xmlDoc *xmlqry);
+
+
+/**
* Retrieve the eurephia lastlog
*
* @version API version level 2
diff --git a/database/eurephiadb_mapping.c b/database/eurephiadb_mapping.c
index 52c2909..6ae289d 100644
--- a/database/eurephiadb_mapping.c
+++ b/database/eurephiadb_mapping.c
@@ -58,6 +58,7 @@ const char *TABLE_NAME[] = {
"blacklist", // TABLE_BLACKLIST
"eurephia_adminaccess", // TABLE_EUREPHIAADMACC
"firewall_profiles", // TABLE_FWPROFILES
+ "plugins", // TABLE_PLUGINS
NULL};
/**
@@ -146,6 +147,10 @@ eDBfieldMap *eDBgetTableFieldMapping(int table) {
srcmap = eTblMap_fwprofiles;
break;
+ case TABLE_PLUGINS:
+ srcmap = eTblMap_plugins;
+ break;
+
default:
return NULL;
}
@@ -307,6 +312,29 @@ eDBfieldMap *eDBxmlMapping(eurephiaCTX *ctx, eDBfieldMap *dbmap, const char *tbl
NULL)
: strdup(""));
}
+
+ case ft_BOOL:
+ // Normalise boolean values.
+ //
+ // A boolean value will be either 't' (true) or 'f' (false)
+ // Unknonw/invalid values will be interpreted as false.
+ //
+ if( nptr->children != NULL ) {
+ switch (nptr->children->content[0]) {
+ case '1':
+ case 't':
+ case 'T':
+ case 'y':
+ case 'Y':
+ ptr->value = strdup("t");
+ break;
+ default:
+ ptr->value = strdup("f");
+ break;
+ }
+ } else {
+ ptr->value = strdup("f");
+ }
break;
default:
@@ -407,8 +435,8 @@ const char *eDBmkSortKeyString(eDBfieldMap *tfmap, const char *skeys_str) {
* @return Returns a bit-wise OR'ed value of all fields in an eDBfieldMap which have their values
* set to something else than NULL.
*/
-long int eDBmappingFieldsPresent(eDBfieldMap *map) {
- long int ret = 0;
+unsigned long long eDBmappingFieldsPresent(eDBfieldMap *map) {
+ long long int ret = 0;
eDBfieldMap *p = NULL;
// Loops through all elements and flags those
@@ -423,15 +451,15 @@ long int eDBmappingFieldsPresent(eDBfieldMap *map) {
/**
- * Retrieves the value of a field in a eDBfieldMap pointer chain.
+ * Looks up a given fieldMap entry to a given field
*
* @param map eDBfieldMap with the values
* @param field_id The field ID to retrieve the value from
*
- * @return Returns const char * to the value in the eDBfieldMap on success, or NULL if either the
- * value is not found or if the value is not set.
+ * @returns the pointer to the fieldMap entry on success, otherwise NULL
*/
-const char *eDBmappingGetValue(eDBfieldMap *map, long field_id) {
+static eDBfieldMap *_eDBmappingGetFieldMapEntry(eDBfieldMap *map, long long field_id)
+{
eDBfieldMap *ptr = NULL;
if( map == NULL ) {
@@ -440,9 +468,42 @@ const char *eDBmappingGetValue(eDBfieldMap *map, long field_id) {
for( ptr = map; ptr != NULL; ptr = ptr->next ) {
if( ptr->field_id == field_id ) {
- return ptr->value;
+ return ptr;
}
}
return NULL;
}
+/**
+ * Retrieves the value of a field in a eDBfieldMap pointer chain.
+ *
+ * @param map eDBfieldMap with the values
+ * @param field_id The field ID to retrieve the value from
+ *
+ * @return Returns const char * to the value in the eDBfieldMap on success, or NULL if either the
+ * value is not found or if the value is not set.
+ */
+const char *eDBmappingGetValue(eDBfieldMap *map, long long field_id) {
+ eDBfieldMap *ptr = _eDBmappingGetFieldMapEntry(map, field_id);
+ return (ptr != NULL ? ptr->value : NULL);
+}
+
+
+/**
+ * Sets the value of a field in a eDBfieldMap pointer chain.
+ *
+ * @param map eDBfieldMap with the values
+ * @param field_id The field ID to modify
+ * @param value String pointer to the value to use
+ *
+ * @return Returns 1 on success, otherwise 0
+ */
+int eDBmappingSetValue(eDBfieldMap *map, long long field_id, char *value) {
+ eDBfieldMap *ptr = _eDBmappingGetFieldMapEntry(map, field_id);
+ if( ptr != NULL ) {
+ ptr->value = strdup_nullsafe(value);
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/database/eurephiadb_mapping.h b/database/eurephiadb_mapping.h
index 540ce3c..8afeb34 100644
--- a/database/eurephiadb_mapping.h
+++ b/database/eurephiadb_mapping.h
@@ -43,7 +43,7 @@
/**
* Enumeration of different field types
*/
-typedef enum eDBfieldType_e { ft_UNDEF, ft_INT, ft_STRING, ft_STRING_LOWER, ft_DATETIME, ft_PASSWD, ft_SETNULL } eDBfieldType;
+typedef enum eDBfieldType_e { ft_UNDEF, ft_INT, ft_STRING, ft_STRING_LOWER, ft_DATETIME, ft_PASSWD, ft_SETNULL, ft_BOOL } eDBfieldType;
/**
* Enumeration of different SQL filter types (IS NULL, =, !=, <=, >=, >, <, etc)
@@ -60,7 +60,7 @@ typedef struct _eDBfieldMap_s {
int tableid; /**< @see TABLE_USERS */
char *table_alias; /**< If the table needs an alias in the SQL query,
it should be set here*/
- long field_id; /**< @see FIELD_NONE */
+ unsigned long long field_id; /**< @see FIELD_NONE */
eDBfieldType field_type; /**< Defines what kind of data this field stores */
eDBfieldFilterType filter_type; /**< Only for WHERE sections, defines what kind of filter
mode to use */
@@ -86,6 +86,7 @@ extern const char *SESSION_STATUS[];
#define TABLE_BLACKLIST 0x06
#define TABLE_EUREPHIAADMACC 0x07
#define TABLE_FWPROFILES 0x08
+#define TABLE_PLUGINS 0x09
/**
* @}
*/
@@ -97,42 +98,46 @@ extern const char *SESSION_STATUS[];
* fields can be processed in a bit-wise manner by some functions.
* @{
*/
-#define FIELD_NONE 0x0000000 /**< Special field */
-#define FIELD_RECID 0x0000001 /**< Special field, should be used to indicate primary key of the table */
-#define FIELD_UID 0x0000002
-#define FIELD_CERTID 0x0000004
-#define FIELD_UNAME 0x0000008
-#define FIELD_ACTIVATED 0x0000010
-#define FIELD_DEACTIVATED 0x0000020
-#define FIELD_LASTACCESS 0x0000040
-
-#define FIELD_CERTDEPTH 0x0000080
-#define FIELD_CNAME 0x0000100
-#define FIELD_EMAIL 0x0000200
-#define FIELD_ORG 0x0000400
-#define FIELD_REGISTERED 0x0000800
-
-#define FIELD_REMOTEIP 0x0001000
-#define FIELD_VPNIP 0x0002000
-#define FIELD_ATTEMPTS 0x0004000
-#define FIELD_LASTATTEMPT 0x0008000
-
-#define FIELD_SESSTATUS 0x0010000
-#define FIELD_LOGIN 0x0020000
-#define FIELD_LOGOUT 0x0040000
-#define FIELD_PASSWD 0x0080000
-#define FIELD_CERTDIGEST 0x0100000
-
-#define FIELD_ACCPROFILE 0x0200000
-
-#define FIELD_INTERFACE 0x0400000
-#define FIELD_ACCESSLVL 0x0800000
-
-#define FIELD_MACADDR 0x1000000
-#define FIELD_UICID 0x2000000
-
-#define FIELD_DESCR 0x4000000
-#define FIELD_FWPROFILE 0x8000000
+#define FIELD_NONE 0x00000000LL /**< Special field */
+#define FIELD_RECID 0x00000001LL /**< Special field, should be used to indicate primary key of the table */
+#define FIELD_UID 0x00000002LL
+#define FIELD_CERTID 0x00000004LL
+#define FIELD_UNAME 0x00000008LL
+#define FIELD_ACTIVATED 0x00000010LL
+#define FIELD_DEACTIVATED 0x00000020LL
+#define FIELD_LASTACCESS 0x00000040LL
+
+#define FIELD_CERTDEPTH 0x00000080LL
+#define FIELD_CNAME 0x00000100LL
+#define FIELD_EMAIL 0x00000200LL
+#define FIELD_ORG 0x00000400LL
+#define FIELD_REGISTERED 0x00000800LL
+
+#define FIELD_REMOTEIP 0x00001000LL
+#define FIELD_VPNIP 0x00002000LL
+#define FIELD_ATTEMPTS 0x00004000LL
+#define FIELD_LASTATTEMPT 0x00008000LL
+
+#define FIELD_SESSTATUS 0x00010000LL
+#define FIELD_LOGIN 0x00020000LL
+#define FIELD_LOGOUT 0x00040000LL
+#define FIELD_PASSWD 0x00080000LL
+#define FIELD_CERTDIGEST 0x00100000LL
+
+#define FIELD_ACCPROFILE 0x00200000LL
+
+#define FIELD_INTERFACE 0x00400000LL
+#define FIELD_ACCESSLVL 0x00800000LL
+
+#define FIELD_MACADDR 0x01000000LL
+#define FIELD_UICID 0x02000000LL
+
+#define FIELD_DESCR 0x04000000LL
+#define FIELD_FWPROFILE 0x08000000LL
+
+#define FIELD_TYPE 0x10000000LL
+#define FIELD_FILE 0x20000000LL
+#define FIELD_CONFIG 0x40000000LL
/**
* @}
*/
@@ -255,6 +260,19 @@ static eDBfieldMap eTblMap_fwprofiles[] = {
{0, NULL, FIELD_NONE, ft_UNDEF, flt_NOTSET, NULL, NULL, NULL}
};
+/**
+ * Unified eurephia field names for the 'plugins' table
+ */
+static eDBfieldMap eTblMap_plugins[] = {
+ {TABLE_PLUGINS, NULL, FIELD_DESCR, ft_STRING , flt_EQ, "name", NULL, NULL},
+ {TABLE_PLUGINS, NULL, FIELD_TYPE, ft_STRING , flt_EQ, "type", NULL, NULL},
+ {TABLE_PLUGINS, NULL, FIELD_FILE, ft_STRING , flt_EQ, "dsofile", NULL, NULL},
+ {TABLE_PLUGINS, NULL, FIELD_CONFIG, ft_STRING , flt_EQ, "config", NULL, NULL},
+ {TABLE_PLUGINS, NULL, FIELD_ACTIVATED, ft_BOOL , flt_EQ, "enabled", NULL, NULL},
+ {TABLE_PLUGINS, NULL, FIELD_RECID, ft_INT , flt_EQ, "plugin_id", NULL, NULL},
+ {0, NULL, FIELD_NONE, ft_UNDEF, flt_NOTSET, NULL, NULL, NULL}
+};
+
#endif // #ifdef EUREPHIADB_MAPPING_C
#ifdef HAVE_LIBXML2
@@ -263,8 +281,9 @@ static eDBfieldMap eTblMap_fwprofiles[] = {
void eDBfreeMapping(eDBfieldMap *p);
eDBfieldMap *eDBxmlMapping(eurephiaCTX *ctx, eDBfieldMap *dbmap, const char *tblalias, xmlNode *fmap_n);
const char *eDBmkSortKeyString(eDBfieldMap *tfmap, const char *skeys_str);
-long int eDBmappingFieldsPresent(eDBfieldMap *map);
-const char *eDBmappingGetValue(eDBfieldMap *map, long field_id);
+unsigned long long eDBmappingFieldsPresent(eDBfieldMap *map);
+const char *eDBmappingGetValue(eDBfieldMap *map, long long field_id);
+int eDBmappingSetValue(eDBfieldMap *map, long long field_id, char *value);
#endif // HAVE_LIBXML2
#endif // !EUREPHIADB_MAPPING_H
diff --git a/database/sqlite/CMakeLists.txt b/database/sqlite/CMakeLists.txt
index a0a2dc8..4002f02 100644
--- a/database/sqlite/CMakeLists.txt
+++ b/database/sqlite/CMakeLists.txt
@@ -1,6 +1,6 @@
# cmake rules for eurephia - SQLite3 database driver
#
-# GPLv2 only - Copyright (C) 2008 - 2012
+# GPLv2 only - Copyright (C) 2008 - 2013
# David Sommerseth <dazo@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or
@@ -45,6 +45,8 @@ SET(edb_sqlite_SRC
sqlite.c
edb-sqlite.c
../../common/eurephiadb_session_common.c
+ ../../auth/eurephia_authplugin.c
+ ../../auth/eurephia_authplugin_driver.c
)
IF(ADMIN_ENABLED)
@@ -58,12 +60,13 @@ IF(ADMIN_ENABLED)
administration/useraccount.c
administration/certificates.c
administration/lastlog.c
+ administration/plugins.c
)
ENDIF(ADMIN_ENABLED)
# Compiler settings
ADD_DEFINITIONS(-D_GNU_SOURCE)
-INCLUDE_DIRECTORIES(BEFORE ../../common/ ../../plugin/ ../../plugin/firewall ../)
+INCLUDE_DIRECTORIES(BEFORE ../../common/ ../../auth/ ../../plugin/ ../../plugin/firewall ../)
#
# Build instructions
diff --git a/database/sqlite/administration/plugins.c b/database/sqlite/administration/plugins.c
new file mode 100644
index 0000000..4816437
--- /dev/null
+++ b/database/sqlite/administration/plugins.c
@@ -0,0 +1,344 @@
+/* plugins.c -- Functions for managing eurephia plug-ins
+ *
+ * GPLv2 only - Copyright (C) 2009 - 2012
+ * 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; version 2
+ * of the License.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**
+ * @file sqlite/administration/plugins.c
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2009-03-28
+ *
+ * @brief Functions for managing eurephia plug-ins
+ *
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <libxml/tree.h>
+
+#include <sqlite3.h>
+
+#include <eurephia_nullsafe.h>
+#include <eurephia_context.h>
+#include <eurephia_log.h>
+#include <eurephia_xml.h>
+#include <eurephia_values.h>
+#include <eurephiadb_session_struct.h>
+#include <eurephiadb_mapping.h>
+#include <passwd.h>
+
+#include "../sqlite.h"
+
+#define FMAP_PLUGINS
+#include "../fieldmapping.h"
+
+
+/**
+ * Internal function. Queries the database for a list of plug-ins
+ *
+ * @param ctx eurephiaCTX
+ * @param fmap eDBfieldMap containing the search criteria
+ *
+ * @return Returns a valid eurephia XML document on success, otherwise NULL
+ */
+static xmlDoc *plugins_search(eurephiaCTX *ctx, eDBfieldMap *fmap)
+{
+ dbresult *res = NULL;
+ xmlDoc *doc = NULL;
+ xmlNode *root_n = NULL, *rec_n = NULL;
+ int i = 0;
+
+ // Query the database for accesses
+ res = sqlite_query_mapped(ctx, SQL_SELECT,
+ "SELECT plgname, plgtype, plgdsofile, plgconfig,"
+ " plgenabled, plgid"
+ " FROM eurephia_plugins",
+ NULL, fmap, "plgname");
+ if( sqlite_query_status(res) != dbSUCCESS ) {
+ eurephia_log(ctx, LOG_ERROR, 0, "Error querying the database for plugins");
+ sqlite_log_error(ctx, res);
+ sqlite_free_results(res);
+ return NULL;
+ }
+
+ eurephiaXML_CreateDoc(ctx, 1, "plugins", &doc, &root_n);
+ xmlNewProp(root_n, (xmlChar *) "mode", (xmlChar *) "list");
+
+ for( i = 0; i < sqlite_get_numtuples(res); i++ ) {
+ rec_n = xmlNewChild(root_n, NULL, (xmlChar *) "plugin", NULL);
+ sqlite_xml_value(rec_n, XML_ATTR, "plgid", res, i, 5);
+ sqlite_xml_value(rec_n, XML_ATTR, "enabled", res, i, 4);
+ sqlite_xml_value(rec_n, XML_NODE, "name", res, i, 0);
+ sqlite_xml_value(rec_n, XML_NODE, "type", res, i, 1);
+ sqlite_xml_value(rec_n, XML_NODE, "dsofile", res, i, 2);
+ sqlite_xml_value(rec_n, XML_NODE, "config", res, i, 3);
+ }
+ sqlite_free_results(res);
+ return doc;
+}
+
+
+/**
+ * Internal function. Registers a new plug-in
+ *
+ * @param ctx eurephiaCTX
+ * @param fmap eDBfieldMap containing information about the new plug-in
+ *
+ * @return Returns an eurephia ResultMsg XML document, with success message or an error message
+ */
+static xmlDoc *plugins_register(eurephiaCTX *ctx, eDBfieldMap *fmap) {
+ dbresult *res = NULL;
+ xmlDoc *ret = NULL;
+
+ // Check if we have the needed fields, and only the needed fields
+ if( (eDBmappingFieldsPresent(fmap) & (FIELD_DESCR | FIELD_TYPE | FIELD_FILE)) == 0 ) {
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Registering a plug-in requires plug-in name, type and DSO file name");
+ }
+
+ if( eDBmappingGetValue(fmap, FIELD_ACTIVATED) == NULL ) {
+ eDBmappingSetValue(fmap, FIELD_ACTIVATED, "t");
+ }
+
+ res = sqlite_query_mapped(ctx, SQL_INSERT, "INSERT INTO eurephia_plugins", fmap, NULL, NULL);
+ if( sqlite_query_status(res) != dbSUCCESS ) {
+ xmlNode *err_n = NULL;
+
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not register the new plug-in");
+ err_n = sqlite_log_error_xml(ctx, res);
+ ret = eurephiaXML_ResultMsg(ctx, exmlERROR, err_n,
+ "Could not register the the new plug-in");
+ xmlFreeNode(err_n);
+ } else {
+ ret = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL,
+ "Plug-in registered with id %i",
+ res->last_insert_id);
+ }
+ sqlite_free_results(res);
+ return ret;
+}
+
+
+/**
+ * Internal function. Deletes plug-in entry from the database
+ *
+ * @param ctx eurephiaCTX
+ * @param fmap eDBfieldMap containing information about the plug-in(s) to be deleted
+ *
+ * @return Returns an eurephia ResultMsg XML document, with success message or an error message
+ */
+static xmlDoc *plugins_unregister(eurephiaCTX *ctx, eDBfieldMap *fmap)
+{
+ dbresult *res = NULL;
+ xmlDoc *ret = NULL;
+ xmlNode *err_n = NULL;
+ long int fields;
+
+ // Check if we have the needed fields, and only the needed fields
+ fields = eDBmappingFieldsPresent(fmap);
+ if( !(fields & FIELD_FILE) && !(fields & FIELD_RECID) ) {
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Deleting plug-ins only accepts "
+ "DSO filename or plug-in ID");
+ }
+
+ // Find the accessprofile ID based on the fieldmap
+ res = sqlite_query_mapped(ctx, SQL_SELECT,
+ "SELECT DISTINCT authplugin"
+ " FROM openvpn_usercerts"
+ " JOIN eurephia_plugins ON (plgid = authplugin)",
+ NULL, fmap, NULL);
+ if( sqlite_query_status(res) != dbSUCCESS ) {
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not delete the plug-in (1)");
+ err_n = sqlite_log_error_xml(ctx, res);
+ ret = eurephiaXML_ResultMsg(ctx, exmlERROR, err_n,
+ "Could not delete the plug-in");
+ xmlFreeNode(err_n);
+ goto exit;
+ }
+
+ // Remove the usage for this plug-in from all user accounts using it
+ if( sqlite_get_numtuples(res) > 0 ) {
+ dbresult *dres = NULL;
+ int i = 0;
+
+ for( i = 0; i < sqlite_get_numtuples(res); i++ ) {
+ dres = sqlite_query(ctx,
+ "UPDATE openvpn_usercerts "
+ " SET authplugin = NULL"
+ " WHERE authplugin = %q",
+ sqlite_get_value(res, i, 0));
+ if( sqlite_query_status(dres) != dbSUCCESS ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Could not remove the plug-in references");
+ err_n = sqlite_log_error_xml(ctx, res);
+ ret = eurephiaXML_ResultMsg(ctx, exmlERROR, err_n,
+ "Could not remove the plug-in references");
+ sqlite_free_results(dres);
+ xmlFreeNode(err_n);
+ goto exit;
+ }
+ }
+ sqlite_free_results(dres);
+ }
+
+ // Delete requested access profiles from eurephia_plugins
+ res = sqlite_query_mapped(ctx, SQL_DELETE, "DELETE FROM eurephia_plugins",
+ NULL, fmap, NULL);
+ if( sqlite_query_status(res) != dbSUCCESS ) {
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not delete the plug-in registration");
+ err_n = sqlite_log_error_xml(ctx, res);
+ ret = eurephiaXML_ResultMsg(ctx, exmlERROR, err_n,
+ "Could not delete the plug-in registration");
+ xmlFreeNode(err_n);
+ } else {
+ ret = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL, "Plug-in unregistered");
+ }
+ exit:
+ sqlite_free_results(res);
+ return ret;
+}
+
+
+static xmlDoc * plugins_modify(eurephiaCTX *ctx, const char *plgid, const char *plgdso,
+ eDBfieldMap *vals_fmap)
+{
+ dbresult *dbres = NULL;
+ xmlDoc *ret = NULL, *where_d = NULL;
+ xmlNode *where_n = NULL;
+ eDBfieldMap *where_m = NULL;
+ long int fields;
+
+ if( plgid == NULL && plgdso == NULL ) {
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "This operation requires the plugin-id or plugin-dso"
+ " attributes to be present");
+ }
+
+ // Check if we have the needed fields, and only the needed fields
+ fields = eDBmappingFieldsPresent(vals_fmap);
+ if( !(fields & (FIELD_CONFIG|FIELD_ACTIVATED))) {
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "This operation requires configuration string or the enabled flag");
+ }
+
+ // Create a field-map for the where clause
+ eurephiaXML_CreateDoc(ctx, 1, "plugins", &where_d, &where_n);
+ assert( (where_d != NULL) && (where_n != NULL) );
+
+ where_n = xmlNewChild(where_n, NULL, (xmlChar *) "fieldMapping", NULL);
+ xmlNewProp(where_n, (xmlChar *) "table", (xmlChar *) "plugins");
+ if( plgid != NULL ) {
+ xmlNewChild(where_n, NULL, (xmlChar *) "plugin_id", (xmlChar *) plgid);
+ }
+ if( plgdso != NULL ) {
+ xmlNewChild(where_n, NULL, (xmlChar *) "dsofile", (xmlChar *) plgdso);
+ }
+ where_m = eDBxmlMapping(ctx, tbl_sqlite_plugins, NULL, where_n);
+ assert( where_m != NULL );
+
+ dbres = sqlite_query_mapped(ctx, SQL_UPDATE, "UPDATE eurephia_plugins",
+ vals_fmap, where_m, NULL);
+ if( sqlite_query_status(dbres) == dbSUCCESS ) {
+ int num_rows = sqlite_get_affected_rows(dbres);
+ if( num_rows > 0 ) {
+ ret = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL,
+ "%i plug-in %s was updated",
+ num_rows,
+ (num_rows == 1 ? "record" : "records"));
+ } else {
+ ret = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL,
+ "No plug-in records where modified");
+ }
+ } else {
+ xmlNode *err_n = NULL;
+
+ eurephia_log(ctx, LOG_ERROR, 0, "Failed to update user-cert link.(%s: %s)",
+ (plgid != NULL ? "plug-in ID" : "plug-in file"),
+ (plgid != NULL ? plgid : plgdso));
+ err_n = sqlite_log_error_xml(ctx, dbres);
+ ret = eurephiaXML_ResultMsg(ctx, exmlERROR, err_n,
+ "Failed to update user-cert link.(%s: %s)",
+ (plgid != NULL ? "plug-in ID" : "plug-in file"),
+ (plgid != NULL ? plgid : plgdso));
+ xmlFreeNode(err_n);
+ }
+ sqlite_free_results(dbres);
+ eDBfreeMapping(where_m);
+ xmlFreeDoc(where_d);
+
+ return ret;
+}
+
+
+/**
+ * @copydoc eDBadminPlugins()
+ */
+xmlDoc *eDBadminPlugins(eurephiaCTX *ctx, xmlDoc *xmlqry)
+{
+ eDBfieldMap *fmap = NULL;
+ char *mode = NULL;
+ xmlDoc *resxml = NULL;
+ xmlNode *root_n = NULL, *fieldmap_n = NULL;
+
+ DEBUG(ctx, 20, "Function call: eDBadminPlugins(ctx, {xmlDoc})");
+ assert( (ctx != NULL) && (xmlqry != NULL) );
+
+ if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
+ eurephia_log(ctx, LOG_CRITICAL, 0,
+ "eurephia admin function call attempted with wrong context type");
+ return NULL;
+ }
+
+ root_n = eurephiaXML_getRoot(ctx, xmlqry, "plugins", 1);
+ if( root_n == NULL ) {
+ eurephia_log(ctx, LOG_CRITICAL, 0, "Invalid XML input.");
+ return NULL;
+ }
+ mode = xmlGetAttrValue(root_n->properties, "mode");
+ if( mode == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0, "Missing mode attribute");
+ return NULL;
+ }
+
+ fieldmap_n = xmlFindNode(root_n, "fieldMapping");
+ if( fieldmap_n == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0, "Missing fieldMapping");
+ }
+ fmap = eDBxmlMapping(ctx, tbl_sqlite_plugins, NULL, fieldmap_n);
+
+ if( strcmp(mode, "search") == 0 ) {
+ resxml = plugins_search(ctx, fmap);
+ } else if( strcmp(mode, "register") == 0 ) {
+ resxml = plugins_register(ctx, fmap);
+ } else if( strcmp(mode, "unregister") == 0 ) {
+ resxml = plugins_unregister(ctx, fmap);
+ } else if( strcmp(mode, "modify") == 0 ) {
+ char *plgid = xmlGetAttrValue(root_n->properties, "plugin-id");
+ char *plgdso = xmlGetAttrValue(root_n->properties, "plugin-dso");
+ resxml = plugins_modify(ctx, plgid, plgdso, fmap);
+ } else {
+ eurephia_log(ctx, LOG_ERROR, 0, "Plug-ins - Unknown mode: '%s'", mode);
+ resxml = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Unknown mode '%s'", mode);
+ }
+ eDBfreeMapping(fmap);
+ return resxml;
+}
diff --git a/database/sqlite/edb-sqlite.c b/database/sqlite/edb-sqlite.c
index 25e6f8b..6e33267 100644
--- a/database/sqlite/edb-sqlite.c
+++ b/database/sqlite/edb-sqlite.c
@@ -1,7 +1,7 @@
/* edb-sqlite.c -- Main driver for eurephia authentication plugin for OpenVPN
* This is the SQLite database driver
*
- * GPLv2 only - Copyright (C) 2008 - 2012
+ * GPLv2 only - Copyright (C) 2008 - 2013
* David Sommerseth <dazo@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or
@@ -274,6 +274,95 @@ int eDBauth_TLS(eurephiaCTX *ctx, const char *org, const char *cname, const char
/**
+ * @copydoc eDBauth_GetAuthMethod()
+ */
+eDBauthMethodResult * eDBauth_GetAuthMethod(eurephiaCTX *ctx,
+ const int certid, const char *username)
+{
+ dbresult *dbr = NULL;
+ eDBauthMethodResult *ret = NULL;
+
+ DEBUG(ctx, 20, "Function call: eDBauth_GetAuthMethod(ctx, %i, '%s')", certid, username);
+
+ dbr = sqlite_query(ctx,
+ "SELECT uicid, authplugin, authusername, activated, deactivated, "
+ " bl1.blid, bl2.blid, plgenabled"
+ " FROM openvpn_usercerts uc"
+ " JOIN openvpn_users ou USING (uid)"
+ " LEFT JOIN eurephia_plugins ep ON (uc.authplugin == ep.plgid)"
+ " LEFT JOIN openvpn_blacklist bl1 ON(ou.username = bl1.username) "
+ " LEFT JOIN (SELECT blid, certid "
+ " FROM openvpn_certificates "
+ " JOIN openvpn_blacklist USING(digest)) bl2 "
+ " ON (uc.certid = bl2.certid)"
+ " WHERE ou.username = '%q' AND uc.certid = '%i'",
+ username, certid);
+
+ if (dbr == NULL) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Failed to query eurephia database for authentication methods for"
+ "user '%s' with certid '%i'", username, certid);
+ return NULL;
+ }
+
+ ret = malloc_nullsafe(ctx, sizeof(eDBauthMethodResult)+2);
+ if (ret == NULL) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Failed to allocate memory fir auth method results");
+ return NULL;
+ }
+
+ /* Some sane and restrictive default values */
+ ret->method = eAM_UNDEF;
+ ret->username = NULL;
+ ret->authplugid = 0;
+ ret->uicid = 0;
+
+ if (sqlite_get_numtuples(dbr) == 1) {
+ char *auplgid = sqlite_get_value(dbr, 0, 1);
+ char *auuname = sqlite_get_value(dbr, 0, 2);
+ char *auplgenab = sqlite_get_value(dbr, 0, 7);
+
+ if( sqlite_get_value(dbr, 0, 5) != NULL ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "User account is BLACKLISTED (%s)",
+ username);
+ ret->method = eAM_BLACKLISTED;
+ } else if( sqlite_get_value(dbr, 0, 6) != NULL ) {
+ eurephia_log(ctx, LOG_WARNING, 0,
+ "User account linked with a BLACKLISTED certificate "
+ "(%s) - certid: %s",
+ username, certid);
+ ret->method = eAM_BLACKLISTED;
+ } else if( sqlite_get_value(dbr, 0, 3) == NULL ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "User account is not activated (%s)",
+ username);
+ ret->method = eAM_INACTIVE;
+ } else if( sqlite_get_value(dbr, 0, 4) != NULL ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "User account is deactivated (%s)",
+ username);
+ ret->method = eAM_INACTIVE;
+ } else if ((auplgid != NULL) && (auplgenab != NULL) && (auplgenab[0] == 't')) {
+ /* If an authentication plug-in is defined and enabled. Use a
+ * different auth name if configured as well.
+ */
+ ret->method = eAM_PLUGIN;
+ ret->username = strdup_nullsafe((auuname != NULL ? auuname : username));
+ ret->authplugid = atoi_nullsafe(auplgid);
+ ret->uicid = atoi_nullsafe(sqlite_get_value(dbr, 0, 0));
+ } else {
+ /* If no authentication plug-in is defined, use internal eurephia auth */
+ ret->method = eAM_INTERNDB;
+ ret->username = strdup_nullsafe(username);
+ ret->authplugid = 0;
+ }
+ }
+
+ sqlite_free_results(dbr);
+ return ret;
+}
+
+
+/**
* @copydoc eDBauth_user()
*/
int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const char *passwd)
@@ -297,8 +386,7 @@ int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const
" JOIN openvpn_blacklist USING(digest)) bl2 ON(uc.certid = bl2.certid)"
" WHERE uc.certid = '%i' AND ou.username = '%q'",
certid, username);
- memset(crpwd, 0, strlen_nullsafe(crpwd));
- free_nullsafe(ctx, crpwd);
+
if( sqlite_query_status(res) != dbSUCCESS ) {
eurephia_log(ctx, LOG_FATAL, 0,
"Could not lookup user in database (certid %i, username '%s'", certid, username);
@@ -319,6 +407,7 @@ int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const
eurephia_log(ctx, LOG_WARNING, 0,"Authentication failed for user '%s'. DB error.",
username);
pwdok = 0;
+ uicid = 0;
} else {
crpwd = eurephia_pwd_crypt(ctx, passwd, dbpwd);
pwdok = ((crpwd != NULL) && (strcmp(crpwd, dbpwd) == 0) ? 1 : 0);
@@ -1230,3 +1319,43 @@ eurephiaVALUES *eDBget_blacklisted_ip(eurephiaCTX *ctx) {
return ret;
}
+
+/**
+ * @copydoc eDBget_plugins()
+ */
+eurephiaVALUES *eDBget_plugins(eurephiaCTX *ctx, const char *plgtype) {
+ eurephiaVALUES *ret = NULL;
+ dbresult *res = NULL;
+ int i = 0;
+ char *plgdso = NULL;
+
+ DEBUG(ctx, 20, "Function call eDBget_plugins(ctx, '%s')", plgtype);
+
+ /* Format of the plug-in information: [<dso-filename>]<config string> */
+
+ res = sqlite_query(ctx,
+ "SELECT plgid, "
+ "CASE WHEN plgconfig IS NULL"
+ " THEN '[' || plgdsofile || ']'"
+ " ELSE '[' || plgdsofile || ']' || plgconfig END"
+ " FROM eurephia_plugins"
+ " WHERE plgenabled = 't' "
+ " AND plgtype = '%q'", plgtype);
+
+ if( sqlite_query_status(res) == dbSUCCESS ) {
+ ret = eCreate_value_space(ctx, 21);
+ for( i = 0; i < sqlite_get_numtuples(res); i++ ) {
+ if( ( plgdso = sqlite_get_value(res, i, 1)) != NULL ) {
+ eAdd_value(ctx, ret, sqlite_get_value(res, i, 0), plgdso);
+ }
+ }
+ } else {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Failed to retrieve additional eurephia plug-ins");
+ sqlite_log_error(ctx, res);
+ ret = NULL;
+ }
+ sqlite_free_results(res);
+
+ return ret;
+}
diff --git a/database/sqlite/fieldmapping.h b/database/sqlite/fieldmapping.h
index 496f4ba..2f25b87 100644
--- a/database/sqlite/fieldmapping.h
+++ b/database/sqlite/fieldmapping.h
@@ -138,4 +138,16 @@ static eDBfieldMap tbl_sqlite_blacklist[] = {
};
#endif
+#ifdef FMAP_PLUGINS
+static eDBfieldMap tbl_sqlite_plugins[] = {
+ {TABLE_PLUGINS, NULL, FIELD_DESCR, ft_STRING , flt_EQ, "plgname", NULL, NULL},
+ {TABLE_PLUGINS, NULL, FIELD_TYPE, ft_STRING , flt_EQ, "plgtype", NULL, NULL},
+ {TABLE_PLUGINS, NULL, FIELD_FILE, ft_STRING , flt_EQ, "plgdsofile", NULL, NULL},
+ {TABLE_PLUGINS, NULL, FIELD_CONFIG, ft_STRING , flt_EQ, "plgconfig", NULL, NULL},
+ {TABLE_PLUGINS, NULL, FIELD_ACTIVATED, ft_BOOL , flt_EQ, "plgenabled", NULL, NULL},
+ {TABLE_PLUGINS, NULL, FIELD_RECID, ft_INT , flt_EQ, "plgid", NULL, NULL},
+ {0, NULL, FIELD_NONE, ft_UNDEF, flt_NOTSET, NULL, NULL, NULL}
+};
+#endif
+
#endif /* !FIELDMAPPING_H_ */
diff --git a/database/sqlite/sql-schema-delta-3.sql b/database/sqlite/sql-schema-delta-3.sql
new file mode 100644
index 0000000..b21899d
--- /dev/null
+++ b/database/sqlite/sql-schema-delta-3.sql
@@ -0,0 +1,38 @@
+--
+-- eurephia database schema for SQLite3
+--
+-- This SQL scripts updates the previous SQL schema to the
+-- new schema needed by edb-sqlite v1.4
+--
+-- GPLv2 only - 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; version 2
+-- of the License.
+--
+-- 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, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+--
+
+-- eurephia_plugins - Defines loadable eurephia plug-ins
+-- This table is parsed upon start-up of OpenVPN/eurephia
+CREATE TABLE eurephia_plugins (
+ plgname varchar(32) NOT NULL, -- short name of the plug-in module
+ plgtype varchar(16) NOT NULL, -- plug-in type (auth, firewall, etc)
+ plgdsofile text NOT NULL, -- full path to the plug-in DSO file
+ plgconfig text , -- Optional config data for the plug-in
+ plgenabled boolean NOT NULL, -- Enable/disable the plug-in
+ plgid integer PRIMARY KEY AUTOINCREMENT
+);
+CREATE INDEX eurephia_plugins_name_type ON eurephia_plugins (plgname, plgtype);
+
+ALTER TABLE openvpn_usercerts ADD COLUMN authplugin integer;
+ALTER TABLE openvpn_usercerts ADD COLUMN authusername text;
diff --git a/database/sqlite/sql-schema.sql b/database/sqlite/sql-schema.sql
index 4d05222..746d84f 100644
--- a/database/sqlite/sql-schema.sql
+++ b/database/sqlite/sql-schema.sql
@@ -1,7 +1,7 @@
--
-- eurephia database schema for SQLite3
--
--- GPLv2 only - Copyright (C) 2008 - 2012
+-- GPLv2 only - Copyright (C) 2008 - 2013
-- David Sommerseth <dazo@users.sourceforge.net>
--
-- This program is free software; you can redistribute it and/or
@@ -19,6 +19,17 @@
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
--
+-- eurephia_plugins - Defines loadable eurephia plug-ins
+-- This table is parsed upon start-up of OpenVPN/eurephia
+CREATE TABLE eurephia_plugins (
+ plgname varchar(32) NOT NULL, -- short name of the plug-in module
+ plgtype varchar(16) NOT NULL, -- plug-in type (auth, firewall, etc)
+ plgdsofile text NOT NULL, -- full path to the plug-in DSO file
+ plgconfig text , -- Optional config data for the plug-in
+ plgenabled boolean NOT NULL, -- Enable/disable the plug-in
+ plgid integer PRIMARY KEY AUTOINCREMENT
+);
+CREATE INDEX eurephia_plugins_name_type ON eurephia_plugins (plgname, plgtype);
-- openvpn_certificates - contains mainly X.509 information from SSL certificates
CREATE TABLE openvpn_certificates (
@@ -49,6 +60,8 @@ CREATE TABLE openvpn_usercerts (
uid integer NOT NULL, -- Must be found in openvpn_users
certid integer NOT NULL, -- Must be found in openvpn_certificates
accessprofile integer , -- If not null, it must be found in openvpn_accesses
+ authplugin integer , -- optional, must match eurephia_plugins.plgid if used
+ authusername text , -- optional, alternative username through plug-ins
registered timestamp DEFAULT CURRENT_TIMESTAMP,
uicid integer PRIMARY KEY AUTOINCREMENT -- Unique ID
);
diff --git a/database/sqlite/sqlite.c b/database/sqlite/sqlite.c
index a17f4b0..2122885 100644
--- a/database/sqlite/sqlite.c
+++ b/database/sqlite/sqlite.c
@@ -495,6 +495,7 @@ static char *_build_value_string(eDBfieldMap *ptr) {
val = sqlite3_mprintf("lower('%q')", ptr->value);
break;
+ case ft_BOOL:
case ft_PASSWD:
case ft_STRING:
default:
diff --git a/eurephiadm/CMakeLists.txt b/eurephiadm/CMakeLists.txt
index 3997e64..e0f8f05 100644
--- a/eurephiadm/CMakeLists.txt
+++ b/eurephiadm/CMakeLists.txt
@@ -1,6 +1,6 @@
# cmake rules for eurephia - eurephiadm, console admin utility
#
-# GPLv2 only - Copyright (C) 2008 - 2012
+# GPLv2 only - Copyright (C) 2008 - 2013
# David Sommerseth <dazo@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or
@@ -21,7 +21,7 @@ PROJECT(eurephiadm C)
cmake_minimum_required(VERSION 2.6)
# Compiler settings
-INCLUDE_DIRECTORIES(../common ../database)
+INCLUDE_DIRECTORIES(../common ../auth ../database)
# eurephiadm parameters
SET(EUREPHIADM_XSLT_PATH "${XSLTROOT}/eurephiadm/" CACHE STRING "Path for eurephiadm XSLT templates")
@@ -60,7 +60,9 @@ ADD_EXECUTABLE(eurephiadm
commands/fwprofiles.c
buildinfo.h
commands/buildinfo.c
+ commands/plugins.c
../common/eurephiadb_session_common.c
+ ../auth/eurephia_authplugin_driver.c
)
# Man pages to install
diff --git a/eurephiadm/client_context.c b/eurephiadm/client_context.c
index 62f8b71..5f03be9 100644
--- a/eurephiadm/client_context.c
+++ b/eurephiadm/client_context.c
@@ -82,7 +82,7 @@ eurephiaCTX *eurephiaCTX_init(const char *logident, const char *log,
(loglevel > 0 ? loglevel : cfgloglvl));
}
- if( !eDBlink_init(ctx, dbdriver, 2) ) {
+ if( !eDBlink_init(ctx, dbdriver, 4) ) {
eurephia_log(ctx, LOG_PANIC, 0, "Could not load the database driver");
free_nullsafe(ctx, ctx);
return NULL;
diff --git a/eurephiadm/commands.h b/eurephiadm/commands.h
index 66a2c0a..944e8c9 100644
--- a/eurephiadm/commands.h
+++ b/eurephiadm/commands.h
@@ -83,6 +83,9 @@ int cmd_Certificates(eurephiaCTX *, eurephiaSESSION *, eurephiaVALUES *cfg, int
void help_UserCerts();
int cmd_UserCerts(eurephiaCTX *, eurephiaSESSION *, eurephiaVALUES *cfg, int argc, char **argv);
+void help_plugins();
+int cmd_plugins(eurephiaCTX *, eurephiaSESSION *, eurephiaVALUES *cfg, int argc, char **argv);
+
void help_fwProfiles();
int cmd_fwProfiles(eurephiaCTX *, eurephiaSESSION *, eurephiaVALUES *cfg, int argc, char **argv);
@@ -126,6 +129,9 @@ static const eurephiadm_functions cmdline_functions[] = {
{"usercerts", 1, "useradmin", NULL,
"User account/Certificate link management", help_UserCerts, cmd_UserCerts},
+ {"plugins", 1, "config", NULL,
+ "Plug-in management", help_plugins, cmd_plugins},
+
{"fwprofiles", 1, "fwprofiles", NULL,
"Firewall profile management", help_fwProfiles, cmd_fwProfiles},
diff --git a/eurephiadm/commands/plugins.c b/eurephiadm/commands/plugins.c
new file mode 100644
index 0000000..081bd4d
--- /dev/null
+++ b/eurephiadm/commands/plugins.c
@@ -0,0 +1,462 @@
+/* plugins.c -- eurephiadm plugins command:
+ * Manages eurephia plug-ins
+ *
+ * GPLv2 only - 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; version 2
+ * of the License.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**
+ * @file plugins.c
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2013-03-04
+ *
+ * @brief eurephia plugins command, to manage eurephia plug-ins.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef HAVE_LIBXML2
+#include <libxml/tree.h>
+#endif
+
+#define MODULE "eurephia::Plugins" /**< Needed to define the active module before including argparser.h */
+#include <eurephia_nullsafe.h>
+#include <eurephia_context.h>
+#include <eurephia_log.h>
+#include <eurephia_xml.h>
+#include <eurephia_values_struct.h>
+#include <eurephiadb_session_struct.h>
+#include <eurephiadb_mapping.h>
+#include <eurephiadb_driver.h>
+#include <eurephia_values.h>
+#include <eurephia_authplugin_driver.h>
+#include <eurephia_authplugin_func.h>
+
+#include "../argparser.h"
+#include "../xsltparser.h"
+
+
+/**
+ * Help screens for the plugins command
+ *
+ * @param page which help screen to display
+ */
+void display_plugins_help(int page)
+{
+ switch( page ) {
+ case 'l':
+ printf("The plugins list mode will show all registered eurephia plug-ins.\n"
+ "\n"
+ " -v | --verbose Print more plug-in info\n"
+ "\n"
+ "Filters:\n"
+ " -t | --plugin-type <id> Plug-in type ID string\n"
+ );
+ break;
+
+ case 'R':
+ printf("The plugins register mode will register a new eurephia plug-in.\n"
+ "\n"
+ " -p | --plugin <file> Full path to the plug-in to register\n"
+ " -c | --config <string> Set the configuration string for this plug-in"
+ "\n"
+ );
+ break;
+
+ case 'U':
+ printf("The plugins unregister mode will remove a registered plug-in.\n"
+ "\n"
+ " -p | --plugin <file> Full path to the plug-in to register\n"
+ " -i | --plugin-id <ID> Nummeric ID to the plug-in\n"
+ "\n"
+ );
+ break;
+
+ case 'M':
+ printf("The plugins modify mode will update the configuration string.\n"
+ "\n"
+ " -p | --plugin <file> Full path to the plug-in to register\n"
+ " -i | --plugin-id <ID> Nummeric ID to the plug-in\n"
+ " -c | --config <string> Set the configuration string for this plug-in\n"
+ " -d | --disable Disables the plug-in\n"
+ " -e | --enable Enables the plug-in\n"
+ "\n"
+ );
+ break;
+
+ default:
+ printf("Available modes for the plugins command are:\n\n"
+ " -R | --register Register a new plug-in\n"
+ " -U | --unregister Remove a registered plug-in\n"
+ " -M | --modify Modify plug-in parameters\n"
+ " -l | --list List registered plug-ins\n"
+ " -h | --help <mode> Show help\n\n");
+ break;
+ }
+}
+
+
+/**
+ * Help screen wrapper. Used by cmd_Help()
+ */
+void help_plugins()
+{
+ display_plugins_help(0);
+}
+
+
+/**
+ * Help screen wrapper for the plugins help function.
+ *
+ * @param ctx eurephiaCTX
+ * @param sess eurephiaSESSION of the current logged in user
+ * @param cfg eurephiaVALUES struct of the current configuration
+ * @param argc argument count for the eurephiadm command
+ * @param argv argument table for the eurephiadm command
+ *
+ * @return returns 0 on success, otherwise 1.
+ */
+int help_plugins2(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv)
+{
+ e_options pluginsargs[] = {
+ {"--list", "-l", 0},
+ {"--register", "-R", 0},
+ {"--unregister", "-U", 0},
+ {"--modify", "-M", 0},
+ {NULL, NULL, 0}
+ };
+ int i = 1;
+ display_plugins_help(eurephia_getopt(&i, argc, argv, pluginsargs));
+ return 0;
+}
+
+
+/**
+ * plugins list mode. Lists all registered eurephia plugins.
+ *
+ * @param ctx eurephiaCTX
+ * @param sess eurephiaSESSION of the current logged in user
+ * @param cfg eurephiaVALUES struct of the current configuration
+ * @param argc argument count for the eurephiadm command
+ * @param argv argument table for the eurephiadm command
+ *
+ * @return returns 0 on success, otherwise 1.
+ */
+static int list_plugins(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv)
+{
+ xmlDoc *plugins_xml = NULL, *srch_xml = NULL;
+ xmlNode *fmap_n = NULL, *srch_n = NULL;
+ char *xsltparams[] = {"view", "'list'", NULL};
+ int i = 0;
+
+ e_options pluginsargs[] = {
+ {"--help", "-h", 0},
+ {"--plugin-type", "-t", 1},
+ {"--verbose", "-v", 0},
+ {NULL, NULL, 0}
+ };
+
+ eurephiaXML_CreateDoc(ctx, 1, "plugins", &srch_xml, &srch_n);
+ xmlNewProp(srch_n, (xmlChar *) "mode", (xmlChar *) "search");
+
+ fmap_n = xmlNewChild(srch_n, NULL, (xmlChar *) "fieldMapping", NULL);
+ xmlNewProp(fmap_n, (xmlChar *) "table", (xmlChar *) "plugins");
+
+ for( i = 1; i < argc; i++ ) {
+ switch( eurephia_getopt(&i, argc, argv, pluginsargs) ) {
+ case 'v':
+ xsltparams[1] = "'details'";
+ break;
+
+ case 't':
+ xmlNewChild(fmap_n, NULL,
+ (xmlChar *) "type", (xmlChar *) optargs[0]);
+ break;
+
+ case 'h':
+ display_plugins_help('l');
+ xmlFreeDoc(srch_xml);
+ return 0;
+
+ default:
+ xmlFreeDoc(srch_xml);
+ return 1;
+ }
+ }
+
+ plugins_xml = eDBadminPlugins(ctx, srch_xml);
+ xmlFreeDoc(srch_xml);
+ if( plugins_xml == NULL ) {
+ fprintf(stderr, "%s: Error retrieving information about eurephia plug-ins\n",
+ MODULE);
+ return 1;
+ }
+ xslt_print_xmldoc(stdout, cfg, plugins_xml, "plugins.xsl", (const char **) xsltparams);
+ xmlFreeDoc(plugins_xml);
+
+ return 0;
+}
+
+
+/**
+ * plugins register/unregister/modify mode. Registers, unregisters plug-ins
+ * or modify plug-in settings
+ *
+ * @param ctx eurephiaCTX
+ * @param sess eurephiaSESSION of the current logged in user
+ * @param cfg eurephiaVALUES struct of the current configuration
+ * @param argc argument count for the eurephiadm command
+ * @param argv argument table for the eurephiadm command
+ *
+ * @return returns 0 on success, otherwise 1.
+ */
+static int plugins_process(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv)
+{
+ xmlDoc *result_xml = NULL, *srch_xml = NULL;
+ xmlNode *fmap_n = NULL, *srch_n = NULL;
+ eurephiaRESULT *res = NULL;
+ int i = 0, rc = 1, mode = 0;
+ ePluginInfoRW *pluginf = NULL;
+ int enabled = 0, disabled = 0;
+
+ e_options registerargs[] = {
+ {"--help", "-h", 0},
+ {"--plugin", "-p", 1},
+ {"--config", "-c", 1},
+ {NULL, NULL, 0}
+ };
+
+ e_options unregisterargs[] = {
+ {"--help", "-h", 0},
+ {"--plugin", "-p", 1},
+ {"--plugin-id", "-i", 1},
+ {NULL, NULL, 0}
+ };
+
+ e_options modifyargs[] = {
+ {"--help", "-h", 0},
+ {"--plugin", "-p", 1},
+ {"--plugin-id", "-i", 1},
+ {"--config", "-c", 1},
+ {"--disable", "-d", 0},
+ {"--enable", "-e", 0},
+ {NULL, NULL, 0}
+ };
+
+ e_options *pluginsargs = NULL;
+
+ eurephiaXML_CreateDoc(ctx, 1, "plugins", &srch_xml, &srch_n);
+ if( (strcmp(argv[0], "--register") == 0) || (strcmp(argv[0], "-R") == 0) ) {
+ xmlNewProp(srch_n, (xmlChar *) "mode", (xmlChar *) "register");
+ pluginsargs = registerargs;
+ mode = 'R';
+ } else if( (strcmp(argv[0], "--unregister") == 0) || (strcmp(argv[0], "-U") == 0) ) {
+ xmlNewProp(srch_n, (xmlChar *) "mode", (xmlChar *) "unregister");
+ pluginsargs = unregisterargs;
+ mode = 'U';
+ } else if( (strcmp(argv[0], "--modify") == 0) || (strcmp(argv[0], "-M") == 0) ) {
+ xmlNewProp(srch_n, (xmlChar *) "mode", (xmlChar *) "modify");
+ pluginsargs = modifyargs;
+ mode = 'M';
+ } else {
+ fprintf(stderr, "%s: Invalid mode\n", MODULE);
+ xmlFreeDoc(srch_xml);
+ return 1;
+ }
+
+ fmap_n = xmlNewChild(srch_n, NULL, (xmlChar *) "fieldMapping", NULL);
+ xmlNewProp(fmap_n, (xmlChar *) "table", (xmlChar *) "plugins");
+
+ for( i = 1; i < argc; i++ ) {
+ switch( eurephia_getopt(&i, argc, argv, pluginsargs) ) {
+ case 'p':
+ if( mode == 'R' ) {
+ pluginf = ePluginInspect(ctx, optargs[0]);
+ if( pluginf == NULL ) {
+ fprintf(stderr,
+ "Failed to extract plug-in info from '%s'\n",
+ optargs[0]);
+ xmlFreeDoc(srch_xml);
+ return 1;
+ }
+ fprintf(stdout, "Plugin file: %s\n", optargs[0]);
+ fprintf(stdout, "Plugin name: %s (v%s)\n",
+ pluginf->name, pluginf->version);
+ fprintf(stdout, "Plugin type: %s\n",
+ ePluginTypeString((ePluginInfo *) pluginf));
+ xmlNewChild(fmap_n, NULL, (xmlChar *) "name",
+ (xmlChar *) pluginf->name);
+ xmlNewChild(fmap_n, NULL, (xmlChar *) "type",
+ (xmlChar *) ePluginTypeShortString((ePluginInfo *) pluginf));
+ xmlNewChild(fmap_n, NULL, (xmlChar *) "dsofile",
+ (xmlChar *) optargs[0]);
+ ePluginInfoFree(ctx, pluginf);
+ } else if( mode == 'U' ) {
+ xmlNewChild(fmap_n, NULL, (xmlChar *) "dsofile",
+ (xmlChar *) optargs[0]);
+ } else if( mode == 'M' ) {
+ xmlNewProp(srch_n, (xmlChar *) "plugin-dso",
+ (xmlChar *) optargs[0]);
+ }
+ break;
+
+ case 'i':
+ if( mode == 'U' ) {
+ xmlNewChild(fmap_n, NULL, (xmlChar *) "plugin_id",
+ (xmlChar *) optargs[0]);
+ } else if ( mode == 'M' ) {
+ xmlNewProp(srch_n, (xmlChar *) "plugin-id",
+ (xmlChar *) optargs[0]);
+ }
+ break;
+
+ case 'c':
+ xmlNewChild(fmap_n, NULL, (xmlChar *) "config", (xmlChar *) optargs[0]);
+ break;
+
+ case 'd':
+ if( !enabled ) {
+ disabled = 1;
+ xmlNewChild(fmap_n, NULL, (xmlChar *) "enabled", (xmlChar *) "f");
+ } else {
+ fprintf(stderr, "%s: --disabled and --enabled are mutually exclusive\n", MODULE);
+ return 1;
+ }
+ break;
+
+ case 'e':
+ if( !disabled ) {
+ enabled = 1;
+ xmlNewChild(fmap_n, NULL, (xmlChar *) "enabled", (xmlChar *) "t");
+ } else {
+ fprintf(stderr, "%s: --enable and --disabled are mutually exclusive\n", MODULE);
+ return 1;
+ }
+ break;
+
+ case 'h':
+ display_plugins_help(mode);
+ return 0;
+
+ default:
+ return 1;
+ }
+ }
+
+ result_xml = eDBadminPlugins(ctx, srch_xml);
+ xmlFreeDoc(srch_xml);
+ if( result_xml == NULL ) {
+ fprintf(stderr, "%s: Error while processing eurephia plug-in request\n", MODULE);
+ return 1;
+ }
+
+ res = eurephiaXML_ParseResultMsg(ctx, result_xml);
+ if( res == NULL ) {
+ fprintf(stderr, "%s: Error while processing plug-in request. No results returned\n", MODULE);
+ return 1;
+
+ } else {
+ if( res->resultType == exmlERROR ) {
+ fprintf(stderr, "%s: %s\n", MODULE, res->message);
+ rc = 1;
+ } else {
+ fprintf(stdout, "%s: %s\n", MODULE, res->message);
+ rc = 0;
+ }
+ }
+ free_nullsafe(ctx, res);
+ xmlFreeDoc(result_xml);
+
+ return rc;
+}
+
+
+/**
+ * Main function for the plugins command
+ *
+ * @param ctx eurephiaCTX
+ * @param sess eurephiaSESSION of the current logged in user
+ * @param cfg eurephiaVALUES struct of the current configuration
+ * @param argc argument count for the eurephiadm command
+ * @param argv argument table for the eurephiadm command
+ *
+ * @return returns 0 on success, otherwise 1.
+ */
+int cmd_plugins(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv)
+{
+ char **mode_argv;
+ int rc = 0, i = 0, mode_argc = 0;
+ e_options pluginsargs[] = {
+ {"--list", "-l", 0},
+ {"--register", "-R", 0},
+ {"--unregister", "-U", 0},
+ {"--modify", "-M", 0},
+ {"--help", "-h", 0},
+ {NULL, NULL, 0}
+ };
+ int (*mode_fnc) (eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv);
+
+ assert((ctx != NULL) && (ctx->dbc != NULL));
+
+ mode_fnc = NULL;
+ for( i = 1; i < argc; i++ ) {
+ switch( eurephia_getopt(&i, argc, argv, pluginsargs) ) {
+ case 'l':
+ mode_fnc = list_plugins;
+ break;
+
+ case 'R':
+ case 'U':
+ case 'M':
+ mode_fnc = plugins_process;
+ break;
+
+ case 'h':
+ mode_fnc = help_plugins2;
+
+ default:
+ break;
+ }
+ if( mode_fnc != NULL ) {
+ break;
+ }
+ }
+
+ // If we do not have any known mode defined, exit with error
+ if( mode_fnc == NULL ) {
+ fprintf(stderr, "%s: Unknown argument. No mode given\n", MODULE);
+ return 1;
+ }
+
+ // Allocate memory for our arguments being sent to the mode function
+ mode_argv = (char **) calloc(sizeof(char *), (argc - i)+2);
+ assert(mode_argv != NULL);
+
+ // Copy over only the arguments needed for the mode
+ mode_argc = eurephia_arraycp(i, argc, argv, mode_argv, argc);
+
+ // Call the mode function
+ rc = mode_fnc(ctx, sess, cfg, mode_argc, mode_argv);
+ free_nullsafe(ctx, mode_argv);
+
+ return rc;
+
+}
diff --git a/man/eurephia-variables.7 b/man/eurephia-variables.7
index d7bc0a3..1276653 100644
--- a/man/eurephia-variables.7
+++ b/man/eurephia-variables.7
@@ -1,4 +1,4 @@
-.TH "eurephia-variables" "7" "October 2010" "David Sommerseth" ""
+.TH "eurephia-variables" "7" "March 2013" "David Sommerseth" ""
.SH "NAME"
eurephia-variables \- eurephia configuration variables
.SH DESCRIPTION
@@ -56,10 +56,14 @@ The \fBeurephiadm\fR utility uses XSLT templates for generating the output to th
.TP
.B openvpn_devtype
The \fBeurephia-auth\fR plug-in will try to auto-detect the device type, which must be either tun or tap. If this auto-detection fails, this configuration variable needs to be set to \fBtun\fR or \fBtap\fR. This value must correspond to the OpenVPN configuration.
+.SH "AUTHENTICATION"
+.TP
+.B auth_disable_internal
+If this is set to \fB1\fR, \fBeurephia\fR will not authenticate users against the password hashes in the \fBeurephia\fR database. This will enforce usage of an external authentication source via additionally loaded authentication plug-ins. If not set or set to \fB0\fR, the eurephia database will be used if no authentication plug-ins have been configured or it has been disabled.
.SH "SEE ALSO"
\fBeurephiadm\-config\fR(7),
\fBeurephia_init\fR(7),
.br
Administrators Tutorial and Manual
.SH "AUTHOR"
-Copyright (C) 2008\-2012 David Sommerseth <dazo@users.sourceforge.net>
+Copyright (C) 2008\-2013 David Sommerseth <dazo@users.sourceforge.net>
diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt
index 0a52bd6..38b0076 100644
--- a/plugin/CMakeLists.txt
+++ b/plugin/CMakeLists.txt
@@ -1,6 +1,6 @@
# cmake rules for eurephia - OpenVPN authentication plugin
#
-# GPLv2 only - Copyright (C) 2008 - 2012
+# GPLv2 only - Copyright (C) 2008 - 2013
# David Sommerseth <dazo@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or
@@ -65,7 +65,7 @@ ENDIF(NOT HAVE_RT_MQ_OPEN OR NOT HAVE_RT_MQ_CLOSE OR NOT HAVE_RT_MQ_UNLINK OR NO
# Compiler settings
-INCLUDE_DIRECTORIES(../common ../database ./firewall .)
+INCLUDE_DIRECTORIES(../common ../auth ../database ./firewall .)
# Do build in subdirs, if some extra modules are enabled
@@ -96,6 +96,8 @@ ADD_LIBRARY(eurephia-auth MODULE
firewall/eurephiafw.c
firewall/eurephiafw_helpers.c
../common/eurephiadb_session_common.c
+ ../auth/eurephia_authplugin.c
+ ../auth/eurephia_authplugin_driver.c
)
SET_TARGET_PROPERTIES(eurephia-auth PROPERTIES PREFIX "")
diff --git a/plugin/eurephia.c b/plugin/eurephia.c
index 620e6e6..946422f 100644
--- a/plugin/eurephia.c
+++ b/plugin/eurephia.c
@@ -1,6 +1,6 @@
/* eurephia.c -- Main functions for the eurephia authentication module
*
- * GPLv2 only - Copyright (C) 2008 - 2012
+ * GPLv2 only - Copyright (C) 2008 - 2013
* David Sommerseth <dazo@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or
@@ -35,15 +35,20 @@
#include <sys/mman.h>
#include <string.h>
#include <getopt.h>
+#include <unistd.h>
#include <assert.h>
#include <errno.h>
#define EUREPHIA_FWINTF /**< Include the proper eurephiaFWINTF declaration in eurephiaCTX */
#include <eurephiafw_struct.h>
#include <eurephia_context.h>
+#include <eurephia_context.h>
+#include <eurephia_authplugin_driver.h>
+#include <eurephia_authplugin_context.h>
+#include <eurephia_authplugin_func.h>
#include <eurephia_nullsafe.h>
-#include <eurephiadb.h>
#include <eurephiadb_driver.h>
+#include <eurephiadb.h>
#include <eurephiafw.h>
#include <eurephia_values.h>
#include <eurephiadb_session_common.h>
@@ -204,6 +209,11 @@ eurephiaCTX *eurephiaInit(const char const **argv, const char const **envp)
ctx->eurephia_fw_intf = NULL;
}
+ // Initialise authentication plug-ins. If no authentication plug-ins have been enabled,
+ // the authplugs context will be NULL.
+ ctx->authplugs = eAuthPlugin_Init(ctx);
+ ctx->nointernalauth = atoi_nullsafe(eGet_value(ctx->dbc->config, "auth_disable_internal")) > 0;
+
// Prepare an empty disconnected list.
// This one is used to track all clients IP addresses and their corresponding eurephia session ID
// when they disconnect. This is especially needed in TUN mode, the eurephia_learn_address()
@@ -241,6 +251,10 @@ int eurephiaShutdown(eurephiaCTX *ctx)
eFW_unload(ctx);
}
+ if( ctx->authplugs != NULL ) {
+ eAuthPlugin_Close(ctx, ctx->authplugs);
+ }
+
if( (ctx->dbc != NULL) && (ctx->dbc->dbhandle != NULL) ) {
eDBdisconnect(ctx);
}
@@ -345,6 +359,9 @@ int eurephia_tlsverify(eurephiaCTX *ctx, const char **env, const char *depth_str
int eurephia_userauth(eurephiaCTX *ctx, const char **env)
{
eurephiaSESSION *authsess = NULL;
+ eDBauthMethodResult *authmeth = NULL;
+ eAuthPlugin *authplug = NULL;
+ eAuthResult *authres = NULL;
int result = 0, certid = 0;
char *cname, *remport, *ipaddr = NULL;
char *tls_digest = NULL, *tls_id = NULL, *username = NULL;
@@ -453,8 +470,118 @@ int eurephia_userauth(eurephiaCTX *ctx, const char **env)
// If we do not have a valid password cached, check against the user database
chk_pwd:
- result = eDBauth_user(ctx, certid, username, passwd);
- if( result < 1 ) {
+ authmeth = eDBauth_GetAuthMethod(ctx, certid, username);
+ if( authmeth == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0,
+ "Failed to identify authentication method for user '%s' with"
+ "certid %i", username, certid);
+ result = 0;
+ goto exit;
+ }
+
+ switch (authmeth->method) {
+ case eAM_INTERNDB:
+ DEBUG(ctx, 12, "Using internal authentication for user '%s'/certid %i",
+ username, certid);
+ if( ctx->nointernalauth == 0 ) {
+ /* Authenticate against the internal eurephia database */
+ result = eDBauth_user(ctx, certid, username, passwd);
+ } else {
+ eurephia_log(ctx, LOG_WARNING, 0,
+ "Internal authentication has been disabled. Enable "
+ "authentication plug-in for user '%s' with certid %i",
+ username, certid);
+ result = 0;
+ }
+ break;
+
+ case eAM_PLUGIN:
+ authplug = eAuthPlugin_Get(ctx->authplugs, authmeth->authplugid);
+ if( authplug == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0,
+ "Failed to find authentication plug-in %i to authenticate"
+ "user '%s' with certid %i",
+ authmeth->authplugid, username, certid);
+ result = 0;
+ goto exit;
+ }
+ DEBUG(ctx, 12, "Using authentication plugin %i for user '%s'/certid %i",
+ authmeth->authplugid, username, certid);
+
+ /* Authenticate the user via the auth plug-in */
+ authres = authplug->AuthenticateUser(ctx, authmeth->username, passwd);
+ if( authres == NULL ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Invalid response from authentication plug-in %i",
+ authmeth->authplugid);
+ result = 0;
+ goto exit;
+ }
+
+ /* Parse the authentication result */
+ switch( authres->status ) {
+ case eAUTH_FAILED:
+ eurephia_log(ctx, LOG_WARNING, 0,"Authentication failed for user '%s': %s",
+ username, authres->msg);
+ sleep(2);
+ result = -1;
+ break;
+
+ case eAUTH_PLGERROR:
+ eurephia_log(ctx, LOG_ERROR, 0,
+ "Authentication plug-in %i returned with an internal error "
+ "while authenticating user '%s' (uicid: %i): %s",
+ authmeth->authplugid,
+ authmeth->username,
+ authmeth->uicid,
+ authres->msg);
+ result = 0;
+ goto exit;
+
+ case eAUTH_SUCCESS:
+ result = authmeth->uicid;
+ if( authres->msg != NULL ) {
+ eurephia_log(ctx, LOG_INFO, 1,
+ "Authentication plug-in (%i) success response "
+ "for user '%s' (uicid: %i): %s",
+ authmeth->authplugid,
+ authmeth->username,
+ result,
+ authres->msg);
+ }
+ break;
+
+ default:
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Invalid response from authentication plug-in %i when "
+ "authenticating user '%s': %i",
+ authmeth->authplugid, authmeth->username, authres->status);
+ result = 0;
+ break;
+ }
+ break;
+
+ case eAM_BLACKLISTED:
+ DEBUG(ctx, 12, "User '%s'/certid %i is blacklisted", username, certid);
+ result = -1;
+ break;
+
+ case eAM_INACTIVE:
+ DEBUG(ctx, 12, "User '%s' is not activated", username);
+ result = -1;
+ break;
+
+ default:
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Invalid authentication method attempted (%i) for "
+ "user '%s' with certid %i",
+ authmeth->method, username, certid);
+ break;
+ }
+ eDBauth_FreeAuthMethodResult(ctx, authmeth);
+
+ /* If the authentication failed, register the failed attempt */
+ if( result < 0 ) {
eDBregister_attempt(ctx, attempt_IPADDR, ATTEMPT_REGISTER, ipaddr);
eDBregister_attempt(ctx, attempt_CERTIFICATE, ATTEMPT_REGISTER, tls_digest);
eDBregister_attempt(ctx, attempt_USERNAME, ATTEMPT_REGISTER, username);
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index 7dd2b0b..9f13acc 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -1,6 +1,6 @@
# cmake rules for eurephia - utilities
#
-# GPLv2 only - Copyright (C) 2008 - 2012
+# GPLv2 only - Copyright (C) 2008 - 2013
# David Sommerseth <dazo@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or
@@ -25,7 +25,7 @@ cmake_minimum_required(VERSION 2.6)
#
IF(EUREPHIADM)
# Compiler settings
- INCLUDE_DIRECTORIES(../common ../database ../eurephiadm)
+ INCLUDE_DIRECTORIES(../common ../auth ../database ../eurephiadm)
# Add the needed eurephia defines
ADD_DEFINITIONS(-DPLUGINDIR="${PLUGINDIR}")