summaryrefslogtreecommitdiffstats
path: root/database/sqlite/administration
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2009-09-27 16:53:54 +0200
committerDavid Sommerseth <dazo@users.sourceforge.net>2009-09-27 16:53:54 +0200
commitc99768d395f378ab73f1fbd96381b90a51cf6fac (patch)
tree05df2d08dca20b6a7a8a1aace80f34dda4bb9b4f /database/sqlite/administration
parentc580cb90e7df9a2438247b68b60577fa335896b0 (diff)
downloadeurephia-c99768d395f378ab73f1fbd96381b90a51cf6fac.tar.gz
eurephia-c99768d395f378ab73f1fbd96381b90a51cf6fac.tar.xz
eurephia-c99768d395f378ab73f1fbd96381b90a51cf6fac.zip
Moved the remainings of administration.c into administration/authentication.c
Diffstat (limited to 'database/sqlite/administration')
-rw-r--r--database/sqlite/administration/authentication.c364
1 files changed, 364 insertions, 0 deletions
diff --git a/database/sqlite/administration/authentication.c b/database/sqlite/administration/authentication.c
new file mode 100644
index 0000000..e8a30f0
--- /dev/null
+++ b/database/sqlite/administration/authentication.c
@@ -0,0 +1,364 @@
+/* administration.c -- Functions needed for administration tasks
+ *
+ * GPLv2 only - Copyright (C) 2008, 2009
+ * 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 administration.c
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2008-12-03
+ *
+ * @brief Functions needed for the administration interface. This file
+ * primarily takes care of user authentication via the administration API
+ *
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <libxml/tree.h>
+
+/**
+ * @{
+ */
+#ifndef DRIVERAPIVERSION
+# define DRIVERAPIVERSION 2
+#endif
+/**
+ * @}
+ */
+
+#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>
+
+#ifndef DRIVER_MODE
+#define DRIVER_MODE
+#endif
+#include <eurephiadb_driver.h>
+
+#include "../sqlite.h"
+
+#if (DRIVERAPIVERSION > 1) || defined(DOXYGEN)
+/*
+ * API Version 2 functions
+ *
+ */
+
+/**
+ * @copydoc eDBadminAuth()
+ */
+int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, const char *pwd) {
+ dbresult *res = NULL;
+ char *crpwd = NULL, *dbpwd = NULL;
+ char *activated = NULL, *deactivated = NULL, *blid = NULL;
+ int uid = -1, access = 0;
+ char interface;
+
+ DEBUG(ctx, 20, "Function call: eDBadminAuth(ctx, '%s, '%s', 'xxxxxxxx')", req_access, uname);
+
+ assert(ctx != NULL);
+
+ switch( ctx->context_type ) {
+ case ECTX_ADMIN_CONSOLE:
+ interface = 'C';
+ break;
+ case ECTX_ADMIN_WEB:
+ interface = 'W';
+ break;
+ default:
+ eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
+ return 0;
+ }
+
+ if( (strlen_nullsafe(uname) < 4) || (strlen_nullsafe(pwd) < 4) ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "User name and/or password is either null or less than 4 bytes");
+ return 0;
+ }
+
+ //
+ // Authenticate user and password
+ //
+ res = sqlite_query(ctx,
+ "SELECT activated, deactivated, bl.blid, "
+ " password, uid "
+ " FROM openvpn_users ou"
+ " LEFT JOIN openvpn_blacklist bl USING (username)"
+ " WHERE ou.username = '%q'",
+ uname);
+
+ if( res == NULL ) {
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not authenticate user against the database");
+ return 0;
+ }
+
+ if( sqlite_get_numtuples(res) == 1 ) {
+ activated = sqlite_get_value(res, 0, 0);
+ deactivated = sqlite_get_value(res, 0, 1);
+ blid = sqlite_get_value(res, 0, 2);
+ dbpwd = sqlite_get_value(res, 0, 3);
+ uid = atoi_nullsafe(sqlite_get_value(res, 0, 4));
+
+ if( blid != NULL ) {
+ eurephia_log(ctx, LOG_WARNING, 0,
+ "Your user account is BLACKLISTED. You have no access.");
+ sqlite_free_results(res);
+ return 0;
+ }
+
+ if( activated == NULL ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Your user account is not yet activated.");
+ sqlite_free_results(res);
+ return 0;
+ }
+
+ if( deactivated != NULL ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Your user account is deactivated.");
+ sqlite_free_results(res);
+ return 0;
+ }
+
+ if( dbpwd == NULL ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed. DB error.");
+ sqlite_free_results(res);
+ return 0;
+ } else {
+ int pwdok = 0;
+ // Verify the password
+ crpwd = eurephia_pwd_crypt(ctx, pwd, dbpwd);
+ pwdok = ((crpwd != NULL) && (strcmp(crpwd, dbpwd) == 0) ? 1 : 0);
+ memset(crpwd, 0, strlen_nullsafe(crpwd));
+ memset(dbpwd, 0, strlen_nullsafe(dbpwd));
+ free_nullsafe(ctx, crpwd);
+ if( pwdok == 0 ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed.");
+ sleep(2);
+ sqlite_free_results(res);
+ return 0;
+ }
+ }
+ sqlite_free_results(res);
+
+ // Check if access level is granted
+ // (SQLite do not handle advanced joins so well, so we need to
+ // do this check with an extra query)
+ res = sqlite_query(ctx,
+ "SELECT (count(*) = 1) AS access "
+ " FROM eurephia_adminaccess"
+ " WHERE uid = '%i' AND interface = '%c' AND access = '%q'",
+ uid, interface, req_access);
+ if( res == NULL ) {
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not check access level");
+ return 0;
+ }
+ access = atoi_nullsafe(sqlite_get_value(res, 0, 0));
+ sqlite_free_results(res);
+
+ if( access == 0 ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Your account is lacking privileges for this operation");
+ return 0;
+ }
+ } else {
+ eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed. No unique records found.");
+ sqlite_free_results(res);
+ sleep(2);
+ return 0;
+ }
+
+ // If we reach this place, authentication was successful. Return users uid
+ return uid;
+}
+
+
+/**
+ * @copydoc eDBadminValidateSession()
+ */
+int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *req_access) {
+ dbresult *res = NULL;
+ int valid = 0, access = 0, expire_time = 0;
+ char interface;
+
+ DEBUG(ctx, 20, "Function call: eDBadminValidateSession(ctx, '%s, '%s')", sesskey, req_access);
+ assert( (ctx != NULL) && (sesskey != NULL) );
+
+ switch( ctx->context_type ) {
+ case ECTX_ADMIN_CONSOLE:
+ interface = 'C';
+ break;
+ case ECTX_ADMIN_WEB:
+ interface = 'W';
+ break;
+ default:
+ eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
+ return 0;
+ }
+
+ // Check if the session is still valid (not expired) and that this session are allowed to access
+ // the requested access level.
+ expire_time = (60 * atoi_nullsafe(defaultValue(eGet_value(ctx->dbc->config, "eurephiadmin_autologout"),
+ "10")
+ )
+ );
+ res = sqlite_query(ctx,
+ "SELECT (strftime('%%s',CURRENT_TIMESTAMP)-strftime('%%s',last_action)) > %i AS exp,"
+ " (access IS NOT NULL) AS access"
+ " FROM eurephia_adminlog"
+ " LEFT JOIN eurephia_adminaccess USING(uid,interface)"
+ " WHERE status IN (1,2)"
+ " AND sessionkey = '%q'"
+ " AND access = '%q'"
+ " AND interface = '%c'",
+ expire_time, sesskey, req_access, interface);
+
+ if( (res == NULL) ) {
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not validate session");
+ return 0;
+ }
+
+ valid = (atoi_nullsafe(sqlite_get_value(res, 0, 0)) == 0);
+ access = (atoi_nullsafe(sqlite_get_value(res, 0, 1)) == 1);
+ sqlite_free_results(res);
+
+ // If still valid, update last_action
+ if( valid && access ) {
+ res = sqlite_query(ctx,
+ "UPDATE eurephia_adminlog"
+ " SET last_action = CURRENT_TIMESTAMP, status = 2"
+ " WHERE sessionkey = '%q'", sesskey);
+ if( res == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0, "Could not register session activity");
+ }
+ sqlite_free_results(res);
+
+ } else {
+ // If not valid, register session as auto-logged out
+
+ res = sqlite_query(ctx,
+ "UPDATE eurephia_adminlog"
+ " SET logout = CURRENT_TIMESTAMP, status = %i"
+ " WHERE sessionkey = '%q'",
+ (access ? 4 : 5), sesskey);
+ if( res == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0, "Could not register old session as logged out");
+ }
+ sqlite_free_results(res);
+
+ // Delete session variables
+ res = sqlite_query(ctx, "DELETE FROM openvpn_sessions WHERE sessionkey = '%q'",
+ sesskey);
+ if( res == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0,
+ "Could not delete session variables (%s))", sesskey);
+ return 0;
+ }
+ sqlite_free_results(res);
+
+ if( !access ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Your user account is lacking privileges");
+ }
+
+ }
+ return (valid && access);
+}
+
+
+/**
+ * @copydoc eDBadminRegisterLogin()
+ */
+int eDBadminRegisterLogin(eurephiaCTX *ctx, eurephiaSESSION *session) {
+ dbresult *res = NULL;
+ char interface;
+ int uid;
+
+ DEBUG(ctx, 20, "Function call: eDBadminRegisterLogin(ctx, {session}'%s')", session->sessionkey);
+ assert((ctx != NULL) && (session != NULL));
+
+ switch( ctx->context_type ) {
+ case ECTX_ADMIN_CONSOLE:
+ interface = 'C'; break;
+ case ECTX_ADMIN_WEB:
+ interface = 'W'; break;
+ default:
+ eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
+ return 0;
+ }
+
+ // Register login into eurephia_adminlog ... uid, login, interface, sessionkey
+ uid = atoi_nullsafe(eGet_value(session->sessvals, "uid"));
+ res = sqlite_query(ctx,
+ "INSERT INTO eurephia_adminlog "
+ " (uid, interface, status, login, last_action, sessionkey) "
+ "VALUES ('%i','%c',1,CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '%q')",
+ uid, interface, session->sessionkey);
+ if( !res ) {
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not manage to register the session in the database");
+ return 0;
+ }
+ sqlite_free_results(res);
+ return 1;
+}
+
+
+/**
+ * @copydoc eDBadminLogout()
+ */
+int eDBadminLogout(eurephiaCTX *ctx, const char *sessionkey) {
+ dbresult *res = NULL;
+
+ DEBUG(ctx, 20, "Function call: eDBadminLogout(ctx, '%s')", sessionkey);
+ assert((ctx != NULL) && (sessionkey != 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 0;
+ }
+
+ // Update session as logged out
+ res = sqlite_query(ctx,
+ "UPDATE eurephia_adminlog "
+ " SET logout = CURRENT_TIMESTAMP, status = 3"
+ " WHERE sessionkey = '%q'",
+ sessionkey);
+ if( !res ) {
+ eurephia_log(ctx, LOG_FATAL, 0, "Could not manage to register the session as logged out");
+ return 0;
+ }
+ sqlite_free_results(res);
+
+ // Delete session variables
+ res = sqlite_query(ctx, "DELETE FROM openvpn_sessions WHERE sessionkey = '%q'", sessionkey);
+ if( res == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0,
+ "Could not delete session variables (%s))", sessionkey);
+ return 0;
+ }
+ sqlite_free_results(res);
+
+ return 1;
+}
+#endif