summaryrefslogtreecommitdiffstats
path: root/database/sqlite/administration/authentication.c
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2009-09-28 22:37:10 +0200
committerDavid Sommerseth <dazo@users.sourceforge.net>2009-09-28 22:37:10 +0200
commitc91da2939d058ff5645f4275f42ece40ed550b8f (patch)
tree78cdf1c4d213b999c4f1722be659ac21ae636efc /database/sqlite/administration/authentication.c
parentc99768d395f378ab73f1fbd96381b90a51cf6fac (diff)
downloadeurephia-c91da2939d058ff5645f4275f42ece40ed550b8f.tar.gz
eurephia-c91da2939d058ff5645f4275f42ece40ed550b8f.tar.xz
eurephia-c91da2939d058ff5645f4275f42ece40ed550b8f.zip
Reworked and unified admin authentication and registration functions to eDBadminAuthenticate()
eDBadminAuth(), eDBadminValidateSession(), eDBadminRegisterLogin() and eDBadminLogout() are now unfied into one admin function, eDBadminAuthenticate(). This function receives all input as eurephia XML documents.
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