summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2008-12-02 23:42:21 +0100
committerDavid Sommerseth <dazo@users.sourceforge.net>2008-12-02 23:42:21 +0100
commit96b177a197fad3bec1332f2e140cdf3863970cce (patch)
tree487f6b393c56c9341e9c9d50815daa62599a64ab
parentc2528bc62d571baa4801c1c34e2bb92142c6c7bb (diff)
downloadeurephia-96b177a197fad3bec1332f2e140cdf3863970cce.tar.gz
eurephia-96b177a197fad3bec1332f2e140cdf3863970cce.tar.xz
eurephia-96b177a197fad3bec1332f2e140cdf3863970cce.zip
Enhanced the access control by introducing access levels
-rw-r--r--database/eurephiadb_driver.h4
-rw-r--r--database/sqlite/edb-sqlite.c96
-rw-r--r--database/sqlite/sql-schema.sql8
-rw-r--r--eurephiadm/commands.h33
-rw-r--r--eurephiadm/eurephiadm.c10
5 files changed, 105 insertions, 46 deletions
diff --git a/database/eurephiadb_driver.h b/database/eurephiadb_driver.h
index 00c2ba4..e59f2ba 100644
--- a/database/eurephiadb_driver.h
+++ b/database/eurephiadb_driver.h
@@ -86,8 +86,8 @@ int (*eDBstore_session_value) (eurephiaCTX *ctx, eurephiaSESSION *skey, int mode
const char *key, const char *val);
/* API version 2 functions */
-int (*eDBadminAuth) (eurephiaCTX *ctx, const char *uname, const char *pwd);
-int (*eDBadminValidateSession) (eurephiaCTX *ctx, const char *sesskey);
+int (*eDBadminAuth) (eurephiaCTX *ctx, const char *req_acc, const char *uname, const char *pwd);
+int (*eDBadminValidateSession) (eurephiaCTX *ctx, const char *sesskey, const char *req_acc);
int (*eDBadminRegisterLogin) (eurephiaCTX *ctx, eurephiaSESSION *session);
int (*eDBadminLogout) (eurephiaCTX *ctx, eurephiaSESSION *session);
diff --git a/database/sqlite/edb-sqlite.c b/database/sqlite/edb-sqlite.c
index 4227234..220d9f7 100644
--- a/database/sqlite/edb-sqlite.c
+++ b/database/sqlite/edb-sqlite.c
@@ -931,16 +931,23 @@ eurephiaVALUES *eDBget_blacklisted_ip(eurephiaCTX *ctx) {
*/
// Authenticate admin user against user database
-int eDBadminAuth(eurephiaCTX *ctx, const char *uname, const char *pwd) {
+int eDBadminAuth(eurephiaCTX *ctx, const char *req_access, const char *uname, const char *pwd) {
dbresult *res = NULL;
char *crpwd = NULL;
char *activated = NULL, *deactivated = NULL, *blid = NULL;
- int uid = -1, admacc = 0, pwok = 0;
+ int uid = -1, pwok = 0;
+ char interface, *access = NULL;
assert(ctx != NULL);
- if( (ctx->context_type != ECTX_ADMIN_CONSOLE)
- && (ctx->context_type != ECTX_ADMIN_WEB) ) {
+ 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;
}
@@ -957,7 +964,7 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *uname, const char *pwd) {
assert(crpwd != NULL);
res = sqlite_query(ctx,
"SELECT activated, deactivated, bl.blid, "
- " (password = '%q') AS pwok, acc_admin, uid"
+ " (password = '%q') AS pwok, uid "
" FROM openvpn_users ou"
" LEFT JOIN openvpn_blacklist bl USING (username)"
" WHERE ou.username = '%q'",
@@ -965,7 +972,7 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *uname, const char *pwd) {
memset(crpwd, 0, strlen_nullsafe(crpwd));
free_nullsafe(crpwd);
- if( !res ) {
+ if( res == NULL ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not authenticate user against the database");
return 0;
}
@@ -975,8 +982,8 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *uname, const char *pwd) {
deactivated = sqlite_get_value(res, 0, 1);
blid = sqlite_get_value(res, 0, 2);
pwok = atoi_nullsafe(sqlite_get_value(res, 0, 3));
- admacc = atoi_nullsafe(sqlite_get_value(res, 0, 4));
- uid = atoi_nullsafe(sqlite_get_value(res, 0, 5));
+ uid = atoi_nullsafe(sqlite_get_value(res, 0, 4));
+ sqlite_free_results(res);
if( blid != NULL ) {
eurephia_log(ctx, LOG_WARNING, 0,
@@ -997,57 +1004,83 @@ int eDBadminAuth(eurephiaCTX *ctx, const char *uname, const char *pwd) {
return 0;
}
- if( admacc != 1 ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Your user account is lacking privileges");
+ if( pwok != 1 ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed,");
sqlite_free_results(res);
return 0;
}
- if( pwok != 1 ) {
- eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed,");
- 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. Too many records found.");
+ eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed. No unique records found.");
sqlite_free_results(res);
return 0;
}
- sqlite_free_results(res);
// If we reach this place, authentication was successful. Return users uid
return uid;
}
-int eDBadminValidateSession(eurephiaCTX *ctx, char *sesskey) {
+int eDBadminValidateSession(eurephiaCTX *ctx, const char *sesskey, const char *req_access) {
dbresult *res = NULL;
- int valid = 0;
+ int valid = 0, access = 0, expire_time = 0;
+ char interface;
assert( (ctx != NULL) && (sesskey != NULL) );
- if( (ctx->context_type != ECTX_ADMIN_CONSOLE)
- && (ctx->context_type != ECTX_ADMIN_WEB) ) {
+ 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.
+ // 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"
+ "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'",
- (60 * atoi_nullsafe(defaultValue(eGet_value(ctx->dbc->config,
- "eurephiadmin_autologout"),
- "10")
- )),
- sesskey);
+ " AND sessionkey = '%q'"
+ " AND access = '%q'",
+ expire_time, sesskey, req_access);
+
if( (res == NULL) || (sqlite_get_numtuples(res) != 1) ) {
eurephia_log(ctx, LOG_FATAL, 0, "Could not validate session");
return 0;
}
- valid = (atoi_nullsafe(sqlite_get_value(res, 0, 0)) == 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
@@ -1060,6 +1093,10 @@ int eDBadminValidateSession(eurephiaCTX *ctx, char *sesskey) {
eurephia_log(ctx, LOG_ERROR, 0, "Could not register session activity");
}
sqlite_free_results(res);
+
+ if( !access ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Your user account is lacking privileges");
+ }
} else {
// If not valid, register session as auto-logged out
res = sqlite_query(ctx,
@@ -1081,8 +1118,7 @@ int eDBadminValidateSession(eurephiaCTX *ctx, char *sesskey) {
}
sqlite_free_results(res);
}
-
- return valid;
+ return (valid && access);
}
int eDBadminRegisterLogin(eurephiaCTX *ctx, eurephiaSESSION *session) {
diff --git a/database/sqlite/sql-schema.sql b/database/sqlite/sql-schema.sql
index 7fb6769..7f0d1af 100644
--- a/database/sqlite/sql-schema.sql
+++ b/database/sqlite/sql-schema.sql
@@ -15,7 +15,6 @@ CREATE TABLE openvpn_users (
activated timestamp ,
deactivated timestamp ,
last_accessed timestamp ,
- acc_admin boolean ,
uid integer PRIMARY KEY AUTOINCREMENT
);
CREATE UNIQUE INDEX openvpn_users_uname ON openvpn_users(username);
@@ -128,3 +127,10 @@ CREATE TABLE eurephia_adminlog (
CREATE INDEX eurephia_adminlog_uid ON eurephia_adminlog(uid);
CREATE INDEX eurephia_adminlog_sesskey ON eurephia_adminlog(sessionkey);
+CREATE TABLE eurephia_adminaccess (
+ uid integer NOT NULL,
+ interface char NOT NULL, -- C-onsole, W-eb
+ access varchar(64) NOT NULL
+);
+CREATE INDEX eurephia_adminacc_uid ON eurephia_adminaccess (uid);
+CREATE INDEX eurephia_adminacc_uid_intf ON eurephia_adminaccess (uid,interface);
diff --git a/eurephiadm/commands.h b/eurephiadm/commands.h
index 242a5c8..3b78710 100644
--- a/eurephiadm/commands.h
+++ b/eurephiadm/commands.h
@@ -27,6 +27,7 @@
typedef struct {
char *command;
int need_session;
+ char *accesslvl;
char *arghint;
char *helpinfo;
char *helpdescr;
@@ -46,14 +47,30 @@ int cmd_EditConfig(eurephiaCTX *, eurephiaSESSION *, eurephiaVALUES *cfg, int ar
/* Declaration of all commands */
static const eurephiadm_functions cmdline_functions[] = {
- // command, need_session, arghints, helpinfo, helpdescr, function
- {"help", 0, NULL, "This help screen", NULL, cmd_Help},
- {"logout", 1, NULL, "Logout from an open session", NULL, cmd_Logout},
- {"listusers", 1, NULL, "List all registered users", NULL, cmd_ListUsers},
- {"show-config", 1, NULL, "List all config settings", NULL, cmd_ShowCfg},
- {"show-configfile", 0, NULL, "List only config file settings", NULL, cmd_ShowCfg},
- {"config", 1, "[-s|-d] <key>", "Add, delete or show one config setting", NULL, cmd_EditConfig},
- {NULL, 0, NULL, NULL, NULL, NULL}
+ // {command, need_session, acclvl, arghints,
+ // helpinfo, helpdescr, function}
+
+ {"help", 0, NULL, NULL,
+ "This help screen", NULL, cmd_Help},
+
+ {"logout", 1, "login", NULL,
+ "Logout from an open session", NULL, cmd_Logout},
+
+ {"listusers", 1, "useradmin", NULL,
+ "List all registered users", NULL, cmd_ListUsers},
+
+ {"show-config", 1, "config", NULL,
+ "List all config settings", NULL, cmd_ShowCfg},
+
+ {"show-configfile", 0, NULL, NULL,
+ "List only config file settings", NULL, cmd_ShowCfg},
+
+ {"config", 1, "config", "[-s|-d] <key>",
+ "Add, delete or show one config setting", NULL, cmd_EditConfig},
+
+ // End of records marker
+ {NULL, 0, NULL, NULL,
+ NULL, NULL, NULL}
};
#endif /* !COMMANDS_H_ */
diff --git a/eurephiadm/eurephiadm.c b/eurephiadm/eurephiadm.c
index 8eac0a6..3d9d71c 100644
--- a/eurephiadm/eurephiadm.c
+++ b/eurephiadm/eurephiadm.c
@@ -147,7 +147,7 @@ int eurephia_ConnectDB(eurephiaCTX *ctx, const char *argstr) {
return 1;
}
-eurephiaSESSION *do_login(eurephiaCTX *ctx) {
+eurephiaSESSION *do_login(eurephiaCTX *ctx, const char *req_access) {
eurephiaSESSION *session = NULL;
char username[33], password[33];
int uid = 0;
@@ -157,7 +157,7 @@ eurephiaSESSION *do_login(eurephiaCTX *ctx) {
get_console_input(username, 32, "User:", 0);
get_console_input(password, 32, "Password:", 1);
- if( (uid = eDBadminAuth(ctx, username, password)) < 1 ) {
+ if( (uid = eDBadminAuth(ctx, req_access, username, password)) < 1 ) {
// Register failure
memset(username, 0, 33);
memset(password, 0, 33);
@@ -312,10 +312,10 @@ int main(int argc, char **argv) {
rc = 0;
goto exit;
}
- session = do_login(ctx);
+ session = do_login(ctx, call_fnc->accesslvl);
} else {
// Session file found, check if it still is a valid session
- if( eDBadminValidateSession(ctx, sesskey_file) ) {;
+ if( eDBadminValidateSession(ctx, sesskey_file, call_fnc->accesslvl) ) {;
// If valid, load this session
session = create_session(ctx, sesskey_file);
} else {
@@ -326,7 +326,7 @@ int main(int argc, char **argv) {
rc = 0;
goto exit;
}
- session = do_login(ctx);
+ session = do_login(ctx, call_fnc->accesslvl);
}
}
free_nullsafe(sesskey_file);