summaryrefslogtreecommitdiffstats
path: root/database/sqlite/administration/authentication.c
diff options
context:
space:
mode:
Diffstat (limited to 'database/sqlite/administration/authentication.c')
-rw-r--r--database/sqlite/administration/authentication.c254
1 files changed, 194 insertions, 60 deletions
diff --git a/database/sqlite/administration/authentication.c b/database/sqlite/administration/authentication.c
index e8a30f0..75ad991 100644
--- a/database/sqlite/administration/authentication.c
+++ b/database/sqlite/administration/authentication.c
@@ -20,12 +20,11 @@
*/
/**
- * @file administration.c
+ * @file authentication.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
+ * @brief Functions used for authentication of administration sessions.
*
*/
@@ -69,17 +68,30 @@
*
*/
+
/**
- * @copydoc eDBadminAuth()
+ * Authenticate a user for the administration interface. This interface do not
+ * require any certificate validation and is intended for administration utilities
+ * for eurephia. The eurephia context type must be either ECTX_ADMIN_CONSOLE or
+ * ECTX_ADMIN_WEB.
+ *
+ * @param ctx eurephiaCTX - context used for administration task
+ * @param req_access String containing the requested administration access level
+ * @param uname username of the user being authenticated
+ * @param pwd password from the user
+ *
+ * @return Returns an eurephia ResultMsg XML document with the result. On fatal errors, NULL is returned
*/
-int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, const char *pwd) {
+static xmlDoc *auth_user(eurephiaCTX *ctx, const char *req_access, const char *uname, const char *pwd) {
+ xmlDoc *res_d = NULL;
+ xmlNode *info_n = NULL;
dbresult *res = NULL;
char *crpwd = NULL, *dbpwd = NULL;
- char *activated = NULL, *deactivated = NULL, *blid = NULL;
- int uid = -1, access = 0;
+ char *activated = NULL, *deactivated = NULL, *blid = NULL, *uid = NULL;
+ int access = 0;
char interface;
- DEBUG(ctx, 20, "Function call: eDBadminAuth(ctx, '%s, '%s', 'xxxxxxxx')", req_access, uname);
+ DEBUG(ctx, 21, "Function call: auth_user(ctx, '%s, '%s', 'xxxxxxxx')", req_access, uname);
assert(ctx != NULL);
@@ -92,12 +104,13 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, co
break;
default:
eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
- return 0;
+ return NULL;
}
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;
+ eurephia_log(ctx, LOG_WARNING, 0,
+ "Username and/or password is either null or less than 4 bytes");
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Username or password is too short");
}
//
@@ -113,7 +126,7 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, co
if( res == NULL ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not authenticate user against the database");
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
if( sqlite_get_numtuples(res) == 1 ) {
@@ -121,31 +134,31 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, co
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));
+ uid = strdup_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.");
+ "User account '%s' is BLACKLISTED. You have no access.", uname);
sqlite_free_results(res);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
if( activated == NULL ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Your user account is not yet activated.");
+ eurephia_log(ctx, LOG_WARNING, 0, "User account '%s' is not yet activated.", uname);
sqlite_free_results(res);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
if( deactivated != NULL ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Your user account is deactivated.");
+ eurephia_log(ctx, LOG_WARNING, 0, "User account '%s' is deactivated.", uname);
sqlite_free_results(res);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
if( dbpwd == NULL ) {
eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed. DB error.");
sqlite_free_results(res);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
} else {
int pwdok = 0;
// Verify the password
@@ -158,7 +171,7 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, co
eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed.");
sleep(2);
sqlite_free_results(res);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
}
sqlite_free_results(res);
@@ -169,40 +182,56 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, co
res = sqlite_query(ctx,
"SELECT (count(*) = 1) AS access "
" FROM eurephia_adminaccess"
- " WHERE uid = '%i' AND interface = '%c' AND access = '%q'",
+ " WHERE uid = '%q' 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;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,"Failed to validate access level");
}
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;
+ eurephia_log(ctx, LOG_WARNING, 0,
+ "User account '%s' is lacking privileges for this operation", uname);
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
} else {
eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed. No unique records found.");
sqlite_free_results(res);
sleep(2);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Authentication failed");
}
// If we reach this place, authentication was successful. Return users uid
- return uid;
+ info_n = xmlNewNode(NULL, (xmlChar *) "UserAccount");
+ assert( info_n != NULL );
+ xmlNewProp(info_n, (xmlChar *) "uid", (xmlChar *) uid);
+ res_d = eurephiaXML_ResultMsg(ctx, exmlRESULT, info_n, "Successful authentication");
+ xmlFreeNode(info_n);
+ free_nullsafe(ctx, uid);
+ return res_d;
}
/**
- * @copydoc eDBadminValidateSession()
+ * Validates a session key, to see if it still is valid (not auto-logged out or invalid session key)
+ * and to check if they have access to a different access level. The eurephia context type must be
+ * either ECTX_ADMIN_CONSOLE or ECTX_ADMIN_WEB.
+ *
+ * @param ctx eurephiaCTX
+ * @param sesskey String containing the session key to validate
+ * @param req_access String containing the required administration access level
+ *
+ * @return Returns an eurephia ResultMsg XML document with the result. On fatal errors, NULL is returned
*/
-int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *req_access) {
+static xmlDoc *auth_session(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);
+ DEBUG(ctx, 21, "Function call: auth_session(ctx, '%s, '%s')", sesskey, req_access);
assert( (ctx != NULL) && (sesskey != NULL) );
switch( ctx->context_type ) {
@@ -214,12 +243,13 @@ int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *r
break;
default:
eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
- return 0;
+ return NULL;
}
// 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"),
+ expire_time = (60 * atoi_nullsafe(defaultValue(eGet_value(ctx->dbc->config,
+ "eurephiadmin_autologout"),
"10")
)
);
@@ -236,7 +266,7 @@ int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *r
if( (res == NULL) ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not validate session");
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Session authentication failed");
}
valid = (atoi_nullsafe(sqlite_get_value(res, 0, 0)) == 0);
@@ -256,7 +286,6 @@ int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *r
} else {
// If not valid, register session as auto-logged out
-
res = sqlite_query(ctx,
"UPDATE eurephia_adminlog"
" SET logout = CURRENT_TIMESTAMP, status = %i"
@@ -273,29 +302,41 @@ int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *r
if( res == NULL ) {
eurephia_log(ctx, LOG_ERROR, 0,
"Could not delete session variables (%s))", sesskey);
- return 0;
+ } else if( !access ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "User account is lacking privileges");
}
sqlite_free_results(res);
+ }
- if( !access ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Your user account is lacking privileges");
- }
+ if (valid && access) {
+ return eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL, "Session authenticated");
+ } else {
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Session authentication failed");
}
- return (valid && access);
}
/**
- * @copydoc eDBadminRegisterLogin()
+ * Registers the user as logged in after a successful authentication. The user must
+ * be registered as logged in to have a valid session.
+ *
+ * @param ctx eurephiaCTX
+ * @param uid Numeric value if the user ID the session belongs to
+ * @param sesskey String containing the session key
+ *
+ * @return Returns an eurephia ResultMsg XML document with the result. On fatal errors, NULL is returned
*/
-int eDBadminRegisterLogin(eurephiaCTX *ctx, eurephiaSESSION *session) {
+static xmlDoc *register_login(eurephiaCTX *ctx, const int uid, const char *sesskey) {
dbresult *res = NULL;
char interface;
- int uid;
- DEBUG(ctx, 20, "Function call: eDBadminRegisterLogin(ctx, {session}'%s')", session->sessionkey);
- assert((ctx != NULL) && (session != NULL));
+ DEBUG(ctx, 21, "Function call: register_login(ctx, %i, '%s')", uid, sesskey);
+ assert( ctx != NULL );
+
+ if( (sesskey == NULL) || (uid < 1) ) {
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Invalid data for login registration");
+ }
switch( ctx->context_type ) {
case ECTX_ADMIN_CONSOLE:
@@ -304,38 +345,44 @@ int eDBadminRegisterLogin(eurephiaCTX *ctx, eurephiaSESSION *session) {
interface = 'W'; break;
default:
eurephia_log(ctx, LOG_ERROR, 0, "Wrong eurephia context type (0x%04x)", ctx->context_type);
- return 0;
+ return NULL;
}
// 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);
+ uid, interface, sesskey);
if( !res ) {
- eurephia_log(ctx, LOG_FATAL, 0, "Could not manage to register the session in the database");
- return 0;
+ eurephia_log(ctx, LOG_FATAL, 0, "Failed to register the session in the database");
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Failed to register the session in the database");
}
sqlite_free_results(res);
- return 1;
+ return eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL, "Session is registered as logged in");
}
/**
- * @copydoc eDBadminLogout()
+ * Registers a session as logged out. This will require the user to do a new authentication
+ * on next access via the administration interface
+ *
+ * @param ctx eurephiaCTX
+ * @param sessionkey String containing the session key
+ *
+ * @return Returns an eurephia ResultMsg XML document with the result. On fatal errors, NULL is returned
*/
-int eDBadminLogout(eurephiaCTX *ctx, const char *sessionkey) {
+static xmlDoc *register_logout(eurephiaCTX *ctx, const char *sessionkey) {
dbresult *res = NULL;
- DEBUG(ctx, 20, "Function call: eDBadminLogout(ctx, '%s')", sessionkey);
+ DEBUG(ctx, 21, "Function call: register_logout(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;
+ return NULL;
}
// Update session as logged out
@@ -344,21 +391,108 @@ int eDBadminLogout(eurephiaCTX *ctx, const char *sessionkey) {
" 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;
+ if( !res || (sqlite_get_affected_rows(res) == 0) ) {
+ eurephia_log(ctx, LOG_FATAL, 0,
+ "Failed to register the session as logged out (updated %i rows)",
+ sqlite_get_affected_rows(res));
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Failed to register the session as logged out");
}
sqlite_free_results(res);
// Delete session variables
res = sqlite_query(ctx, "DELETE FROM openvpn_sessions WHERE sessionkey = '%q'", sessionkey);
- if( res == NULL ) {
+ if( !res || (sqlite_get_affected_rows(res) == 0) ) {
eurephia_log(ctx, LOG_ERROR, 0,
"Could not delete session variables (%s))", sessionkey);
- return 0;
+ return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
+ "Could not delete session variables (%s))", sessionkey);
}
sqlite_free_results(res);
- return 1;
+ return eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL, "Session is logged out");
+}
+
+
+/**
+ * @copydoc eDBadminAuthenticate()
+ */
+xmlDoc *eDBadminAuthenticate(eurephiaCTX *ctx, xmlDoc *qryxml) {
+ xmlDoc *res_d = NULL;
+ xmlNode *qry_n = NULL;
+ char *mode = NULL;
+ int type = 0;
+
+ DEBUG(ctx, 20, "Function call: eDBadminAuthenticate(ctx, xmlDoc)");
+ assert( (ctx != NULL) && (qryxml != 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;
+ }
+
+ qry_n = eurephiaXML_getRoot(ctx, qryxml, "Authenticate", 1);
+ if( qry_n != NULL ) {
+ type = 1;
+ goto accept;
+ }
+
+ qry_n = eurephiaXML_getRoot(ctx, qryxml, "Register", 1);
+ if( qry_n != NULL ) {
+ type = 2;
+ goto accept;
+ }
+
+ eurephia_log(ctx, LOG_ERROR, 0, "Could not find a valid XML request for eDBadminAuthenticate()");
+ return NULL;
+
+ accept:
+ mode = xmlGetAttrValue(qry_n->properties, "mode");
+ if( mode == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0, "Invalid authentication request");
+ return NULL;
+ }
+
+ switch( type ) {
+ case 1: // Authenticate tag
+ if( strcmp(mode, "user") == 0 ) {
+ // const char *req_access, const char *uname, const char *pwd
+ const char *reqacc = NULL, *uname = NULL, *pwd = NULL;
+ uname = xmlGetNodeContent(qry_n, "username");
+ pwd = xmlGetNodeContent(qry_n, "password");
+ reqacc = xmlGetNodeContent(qry_n, "accesslevel");
+ res_d = auth_user(ctx, reqacc, uname, pwd);
+ } else if ( strcmp(mode, "session") == 0 ) {
+ const char *sesskey = NULL, *reqacc = NULL;
+ sesskey = xmlGetNodeContent(qry_n, "sessionkey");
+ reqacc = xmlGetNodeContent(qry_n, "accesslevel");
+ res_d = auth_session(ctx, sesskey, reqacc);
+ }
+ break;
+
+ case 2: // Register tag
+ if( strcmp(mode, "login") == 0 ) {
+ const char *sesskey = NULL;
+ unsigned int uid = 0;
+
+ uid = atoi_nullsafe(xmlGetAttrValue(qry_n->properties, "uid"));
+ sesskey = xmlExtractContent(qry_n);
+ res_d = register_login(ctx, uid, sesskey);
+ } else if( strcmp(mode, "logout") == 0 ) {
+ const char *sesskey = NULL;
+
+ sesskey = xmlExtractContent(qry_n);
+ res_d = register_logout(ctx, sesskey);
+ }
+ break;
+
+ default:
+ eurephia_log(ctx, LOG_FATAL, 0, "The unthinkable has just happened (type %i)", type);
+ res_d = NULL;
+ break;
+ }
+ return res_d;
}
+
#endif