summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--database/postgresql/edb-pgsql.c1386
1 files changed, 1043 insertions, 343 deletions
diff --git a/database/postgresql/edb-pgsql.c b/database/postgresql/edb-pgsql.c
index e1330b5..eabe4fe 100644
--- a/database/postgresql/edb-pgsql.c
+++ b/database/postgresql/edb-pgsql.c
@@ -1,6 +1,6 @@
/* edb-pgsql.c -- PostgreSQL database driver for eurephia
*
- * GPLv2 only - Copyright (C) 2011
+ * GPLv2 only - Copyright (C) 2011, 2012
* David Sommerseth <dazo@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or
@@ -49,29 +49,155 @@
#include <eurephiadb_session_struct.h>
#include <passwd.h>
+typedef enum { PREPSQL_NONE = 0, PREPSQL_TLS_AUTH, PREPSQL_USERPWD_AUTH,
+ PREPSQL_BLACKLIST_ATTEMPTUPD, PREPSQL_USERS_LASTACC_UPD,
+ PREPSQL_USERS_GETUID, PREPSQL_ATTEMPTS_RESET, PREPSQL_ATTEMPTS_INCR,
+ PREPSQL_ATTEMPTS_REG_CERT, PREPSQL_ATTEMPTS_REG_USERNAME,
+ PREPSQL_ATTEMPTS_REG_IPADDR,
+ PREPSQL_BLACKLIST_CHECK_CERT, PREPSQL_BLACKLIST_CHECK_USERNAME,
+ PREPSQL_BLACKLIST_CHECK_IPADDR,
+ PREPSQL_BLACKLIST_REG_CERT, PREPSQL_BLACKLIST_REG_USERNAME,
+ PREPSQL_BLACKLIST_REG_IPADDR,
+ PREPSQL_SESSIONKEY_GETSEED_SESSION, PREPSQL_SESSIONKEY_GETSEED_AUTH,
+ PREPSQL_SESSIONKEY_GETMAC,
+ PREPSQL_SESSIONKEY_UNIQ_ADMIN, PREPSQL_SESSIONKEY_UNIQ_PLAUTH,
+ PREPSQL_SESSIONKEY_REGISTER, PREPSQL_SESSIONKEY_REMOVE,
+ PREPSQL_SESSIONVARS_LOAD, PREPSQL_SESSIONVARS_STORE_NEW,
+ PREPSQL_SESSIONVARS_STORE_UPDATE, PREPSQL_SESSIONVARS_STORE_DELETE,
+ PREPSQL_SESSIONS_DESTROY_LASTLOG, PREPSQL_SESSIONS_DESTROY_SESS,
+ PREPSQL_REGISTER_LOGIN, PREPSQL_REGISTER_LOGOUT,
+ PREPSQL_MACHISTORY_REGISTER, PREPSQL_MACHISTORY_LASTLOG,
+ PREPSQL_FIREWALL_GETPROFILE
+} _ePG_prepID;
+
+typedef struct {
+ _ePG_prepID prepid;
+ const char *name;
+ unsigned int numargs;
+ unsigned int prepared;
+} _ePGprepStatements_t;
+
+static _ePGprepStatements_t _ePGprepStatements[] = {
+ {.prepid = PREPSQL_TLS_AUTH,
+ .name = "eurephia_tls_auth", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_USERPWD_AUTH,
+ .name = "eurephia_userpwd_auth", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_BLACKLIST_ATTEMPTUPD,
+ .name ="eurephia_blacklist_attupd" , .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_USERS_LASTACC_UPD,
+ .name = "eurephia_users_lastacc_upd", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_USERS_GETUID,
+ .name = "eurephia_getuid", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_ATTEMPTS_RESET,
+ .name = "eurephia_attempts_reset", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_ATTEMPTS_INCR,
+ .name = "eurephia_attempts_increment", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_ATTEMPTS_REG_CERT,
+ .name = "eurephia_attempts_reg_cert", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_ATTEMPTS_REG_USERNAME,
+ .name = "eurephia_attempts_reg_username", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_ATTEMPTS_REG_IPADDR,
+ .name = "eurephia_attempts_reg_ipaddr", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_BLACKLIST_CHECK_CERT,
+ .name = "eurephia_blacklist_check_cert", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_BLACKLIST_CHECK_USERNAME,
+ .name = "eurephia_blacklist_check_username", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_BLACKLIST_CHECK_IPADDR,
+ .name = "eurephia_blacklist_check_cert_ipaddr", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_BLACKLIST_REG_CERT,
+ .name = "eurephia_blacklist_reg_cert", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_BLACKLIST_REG_USERNAME,
+ .name = "eurephia_blacklist_reg_username", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_BLACKLIST_REG_IPADDR,
+ .name = "eurephia_blacklist_reg_ipaddr", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONKEY_GETSEED_SESSION,
+ .name = "eurephia_sessionkey_getseed_session", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONKEY_GETSEED_AUTH,
+ .name = "eurephia_sessionkey_getseed_auth", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONKEY_GETMAC,
+ .name = "eurephia_sessionkey_getmac", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONKEY_UNIQ_ADMIN,
+ .name = "eurephia_sessionkey_uniq_admin", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONKEY_UNIQ_PLAUTH,
+ .name = "eurephia_sessionkey_uniq_plauth", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONKEY_REGISTER,
+ .name = "eurephia_sessionkey_register", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONKEY_REMOVE,
+ .name = "eurephia_sessionkey_remove", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONVARS_LOAD,
+ .name = "eurephia_sessionvars_load", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONVARS_STORE_NEW,
+ .name = "eurephia_sessionvars_store_new", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONVARS_STORE_UPDATE,
+ .name = "eurephia_sessionvars_store_upd", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONVARS_STORE_DELETE,
+ .name = "eurephia_sessionvars_store_del", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONS_DESTROY_LASTLOG,
+ .name = "eurephia_sessions_destr_lastlogupd", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_SESSIONS_DESTROY_SESS,
+ .name = "eurephia_sessions_destr_sessions", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_REGISTER_LOGIN,
+ .name = "eurephia_register_login", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_REGISTER_LOGOUT,
+ .name = "eurephia_register_logout", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_MACHISTORY_REGISTER,
+ .name = "eurephia_machistory_reg", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_MACHISTORY_LASTLOG,
+ .name = "eurephia_machistory_lastlog_upd", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_FIREWALL_GETPROFILE,
+ .name = "eurephia_firewall_getprofile", .numargs = 0, .prepared = 0},
+ {.prepid = PREPSQL_NONE,
+ .name = NULL, .numargs = 0, .prepared = 0},
+};
+
+/* FIXME: Go through the code and place all ePGprepStatement() in a function called from eDBconnect()
+ * Let the SQL be declared in _ePGprepStatements_t ... the prep-function will just loop _ePGprepStatements[]
+ */
+
/**
* Mapping struct - maps attempt types (attempt_IPADDR, attempt_CERTIFICATE, attempt_USERNAME)
* to database field names, configuration options (with default values) and description
*/
typedef struct {
- char *colname; /**< Field when doing look up in blacklist and attempts tables */
- char *colname_where; /**< Field when using column name in WHERE section of SQL queries */
- char *allow_cfg; /**< Configure parameter for the attempt limits */
- char *descr; /**< Description, used to give more readable output for users */
- char *default_value; /**< Default value, if config option is not found */
- char *value_func; /**< If not NULL, the value will be passed through the given SQL function */
+ char *colname; /** Field when doing look up in blacklist and attempts tables */
+ char *colname_where; /** Field when using column name in WHERE section of SQL queries */
+ char *allow_cfg; /** Configure parameter for the attempt limits */
+ char *descr; /** Description, used to give more readable output for users */
+ char *default_value; /** Default value, if config option is not found */
+ char *value_func; /** If not NULL, value will be passed through given SQL function */
+ _ePG_prepID sql_blacklist_check; /** Prepared SQL ID reference for blacklist check queries */
+ _ePG_prepID sql_blacklist_reg; /** Prepared SQL ID reference for blacklist register queries */
+ _ePG_prepID sql_attempts_reg; /** Prepared SQL ID reference for attempts register queries */
} eDBattempt_types_t;
-
+
/**
* Static mapping table with the needed values. Uses the eDBattempt_types_t struct.
*/
static const eDBattempt_types_t eDBattempt_types[] = {
- {NULL, NULL, NULL, NULL},
- {"remoteip\0", "remoteip\0", "allow_ipaddr_attempts\0", "IP Address\0", "10\0", NULL},
- {"digest\0", "lower(digest)\0", "allow_cert_attempts\0", "Certificate\0", "5\0", "lower\0"},
- {"username\0", "username\0", "allow_username_attempts\0", "Username\0", "5\0", NULL},
- {NULL, NULL, NULL, NULL}
+ {NULL},
+ {.colname = "remoteip", .colname_where = "remoteip",
+ .allow_cfg = "allow_ipaddr_attempts", .descr = "IP Address",
+ .default_value = "10", .value_func = NULL,
+ .sql_blacklist_check = PREPSQL_BLACKLIST_CHECK_IPADDR,
+ .sql_blacklist_reg = PREPSQL_BLACKLIST_REG_IPADDR,
+ .sql_attempts_reg = PREPSQL_ATTEMPTS_REG_IPADDR
+ },
+ {.colname = "digest", .colname_where = "lower(digest)",
+ .allow_cfg = "allow_cert_attempts", .descr = "Certificate",
+ .default_value = "5", .value_func = "lower",
+ .sql_blacklist_check = PREPSQL_BLACKLIST_CHECK_CERT,
+ .sql_blacklist_reg = PREPSQL_BLACKLIST_REG_CERT,
+ .sql_attempts_reg = PREPSQL_ATTEMPTS_REG_CERT
+ },
+ {.colname = "username", .colname_where = "username",
+ .allow_cfg = "allow_username_attempts", .descr = "Username",
+ .default_value = "3", .value_func = NULL,
+ .sql_blacklist_check = PREPSQL_BLACKLIST_CHECK_USERNAME,
+ .sql_blacklist_reg = PREPSQL_BLACKLIST_REG_USERNAME,
+ .sql_attempts_reg = PREPSQL_ATTEMPTS_REG_USERNAME
+ },
+ {NULL}
};
@@ -84,43 +210,122 @@ static inline char *ePGgetValue(PGresult *res, int row, int col) {
}
-static void ePGerrorMessage(eurephiaCTX *ctx, PGresult *dbr, int logdst, int loglvl,
- const char *prepsql, const char *fmt, ...)
+int ePGprepStatementGetID(_ePG_prepID prepid)
+{
+ int i;
+ for( i = 0; _ePGprepStatements[i].prepid != PREPSQL_NONE; i++ ) {
+ if( _ePGprepStatements[i].prepid == prepid ) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+#define ePGerrorMessage(ctx, dbr, logdst, loglvl, prepid, fmt...) __ePGerrorMessage(ctx, dbr, logdst,loglvl, prepid, __FILE__, __LINE__, ## fmt)
+static void __ePGerrorMessage(eurephiaCTX *ctx, PGresult *dbr, int logdst, int loglvl,
+ _ePG_prepID prepid, const char *errfile, const long errline,
+ const char *fmt, ...)
{
char msgfmt[514];
va_list ap;
-
+ int id = -1;
+
+ if( prepid != PREPSQL_NONE ) {
+ id = ePGprepStatementGetID(prepid);
+ if( id < 0 ) {
+ eurephia_log(ctx, LOG_ERROR, 0,
+ "Failed to map prepared statement ID %i to "
+ "a valid statement", prepid);
+ return;
+ }
+ }
memset(&msgfmt, 0, 514);
va_start(ap, fmt);
- snprintf(msgfmt, 512, "[%s] SQL query failed: %s: %s",
- prepsql, fmt,
- (dbr != NULL ? PQresultErrorMessage(dbr)
- : (ctx->dbc != NULL ? PQerrorMessage(ctx->dbc->dbhandle) : "[unknown error]")
- ));
+ if( prepid != PREPSQL_NONE ) {
+ snprintf(msgfmt, 512, "[%s] SQL query failed: %s %s: %s",
+ _ePGprepStatements[id].name,
+ (dbr != NULL ? PQresStatus(PQresultStatus(dbr)) : ""), fmt,
+ (dbr != NULL ? PQresultErrorMessage(dbr)
+ : (ctx->dbc != NULL ? PQerrorMessage(ctx->dbc->dbhandle)
+ : "[unknown error]")
+ ));
+ } else {
+ snprintf(msgfmt, 512, "SQL query failed: %s %s: %s",
+ (dbr != NULL ? PQresStatus(PQresultStatus(dbr)) : ""),
+ fmt,
+ (dbr != NULL ? PQresultErrorMessage(dbr)
+ : (ctx->dbc != NULL ? PQerrorMessage(ctx->dbc->dbhandle)
+ : "[unknown error]")
+ ));
+ }
+#ifdef ENABLE_DEBUG
+ _veurephia_log_func(ctx, logdst, loglvl, errfile, errline, ap, msgfmt);
+#else
veurephia_log(ctx, logdst, loglvl, ap, msgfmt);
+#endif
va_end(ap);
memset(&msgfmt, 0, 514);
- PQclear(dbr);
- if( (loglvl == LOG_EMERG) && (ctx->dbc != NULL) ) {
+ if( dbr ) {
+ PQclear(dbr);
+ }
+ if( (loglvl == LOG_EMERG) && (ctx->dbc != NULL)
+ && (PQstatus(ctx->dbc->dbhandle) != CONNECTION_OK) ) {
PQfinish(ctx->dbc->dbhandle);
}
}
-#define PREPSQL_TLS_AUTH "eurephia_tls_auth"
-#define PREPSQL_USERPWD_AUTH "eurephia_userpwd_auth"
-#define PREPSQL_BLACKLIST_ATTEMPTUPD "eurephia_blacklist_attupd"
-#define PREPSQL_USERS_LASTACC_UPD "eurephia_users_lastacc_upd"
-#define PREPSQL_USERS_GETUID "eurephia_getuid"
-#define PREPSQL_BLACKLIST_CHECK "eurephia_blacklist_check"
-#define PREPSQL_ATTEMPTS_CHECK "eurephia_attempts_check"
-#define PREPSQL_BLACKLIST_REGISTER "eurephia_blacklist_reg"
+int ePGprepStatement(eurephiaCTX *ctx, _ePG_prepID prepid, const char *sql, int argc)
+{
+ int id;
+
+ /* Check if this statement is already prepared */
+ id = ePGprepStatementGetID(prepid);
+ if( _ePGprepStatements[id].prepid == prepid ) {
+ PGresult *dbr = NULL;
+ _ePGprepStatements_t *prep = &_ePGprepStatements[id];
+
+ if( prep->prepared == 1 ) {
+ /* statement found, and was already prepared */
+ return id;
+ }
+
+ /* statement found in lookup table, but not prepared in database */
+ dbr = PQprepare(ctx->dbc->dbhandle,
+ prep->name, sql, argc, NULL);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, prepid,
+ "Failed to prepare SQL query: %s", sql);
+ return -2;
+ }
+ PQclear(dbr);
+ _ePGprepStatements[id].numargs = argc;
+ _ePGprepStatements[id].prepared = 1; /* Flag statement as prepared */
+ return id;
+ }
+ return -1;
+};
+
+
+PGresult * ePGprepExec(eurephiaCTX *ctx, int prepid, const char **qry_args) {
+ if( prepid < 0 ) {
+ eurephia_log(ctx, LOG_ERROR, 0,
+ "Invalid prepared statement ID %i", prepid);
+ return NULL;
+ }
+ return PQexecPrepared(ctx->dbc->dbhandle,
+ _ePGprepStatements[prepid].name,
+ _ePGprepStatements[prepid].numargs,
+ qry_args, NULL, NULL, 0);
+}
+
/**
* @copydoc eDB_DriverVersion()
*/
const char *eDB_DriverVersion(void) {
- return "edb-pgsql (v"DRIVERVERSION") David Sommerseth 2011 (C) GPLv2";
+ return "edb-pgsql (v"DRIVERVERSION") David Sommerseth 2012 (C) GPLv2";
}
@@ -132,7 +337,6 @@ int eDB_DriverAPIVersion() {
}
-
/**
* Internal driver function for simplifying update of the blacklist table. It will simply just
* update the 'last_accessed' field in the blacklist table.
@@ -143,23 +347,23 @@ int eDB_DriverAPIVersion() {
static inline void update_blacklist_attempt(eurephiaCTX *ctx, const char *blid) {
if( blid != NULL ) {
PGresult *dbr = NULL;
+ int prepid = -1;
const char ** qry_args = NULL;
- dbr = PQprepare(ctx->dbc->dbhandle, PREPSQL_BLACKLIST_ATTEMPTUPD,
- "UPDATE blacklist "
- " SET last_accessed = CURRENT_TIMESTAMP WHERE blid = $1", 1, NULL);
- if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ prepid = ePGprepStatement(ctx, PREPSQL_BLACKLIST_ATTEMPTUPD,
+ "UPDATE blacklist"
+ " SET last_accessed = CURRENT_TIMESTAMP"
+ " WHERE blid = $1", 1);
+ if( prepid < 0 ) {
ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0, PREPSQL_BLACKLIST_ATTEMPTUPD,
"Preparing last attempt query update failed");
return;
}
- PQclear(dbr);
qry_args = calloc(1, sizeof(char *));
qry_args[0] = blid;
- dbr = PQexecPrepared(ctx->dbc->dbhandle, PREPSQL_BLACKLIST_ATTEMPTUPD, 1,
- qry_args, NULL, NULL, 0);
+ dbr = ePGprepExec(ctx, prepid, qry_args);
free_nullsafe(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0, PREPSQL_BLACKLIST_ATTEMPTUPD,
@@ -172,7 +376,6 @@ static inline void update_blacklist_attempt(eurephiaCTX *ctx, const char *blid)
}
-
/**
* @copydoc eDBconnect()
* Connect to the database ... connection is stored in the eurephiaCTX context
@@ -223,8 +426,8 @@ int eDBconnect(eurephiaCTX *ctx, const int argc, const char **argv)
}
if( PQstatus(dbc->dbhandle) != CONNECTION_OK ) {
- ePGerrorMessage(ctx, NULL, LOG_EMERG, 0, "DB-INIT",
- "Failed to connect to the PostgreSQL database '%s'",
+ ePGerrorMessage(ctx, NULL, LOG_EMERG, 0, PREPSQL_NONE,
+ "[DB-INIT] Failed to connect to the PostgreSQL database '%s'",
dbname);
ctx->dbc = NULL;
free_nullsafe(ctx, dbc);
@@ -254,8 +457,8 @@ int eDBconnect(eurephiaCTX *ctx, const int argc, const char **argv)
dbc->config = cfg;
PQclear(res);
} else {
- ePGerrorMessage(ctx, res, LOG_EMERG, 0, "DB-INIT",
- "Failed to the configuration from the database");
+ ePGerrorMessage(ctx, res, LOG_EMERG, 0, PREPSQL_NONE,
+ "[DB-INIT] Failed to the configuration from the database");
eFree_values(ctx, dbc->dbparams);
free_nullsafe(ctx, dbc);
return 0;
@@ -264,6 +467,9 @@ int eDBconnect(eurephiaCTX *ctx, const int argc, const char **argv)
}
+/**
+ * @copydoc eDBdisconnect()
+ */
void eDBdisconnect(eurephiaCTX *ctx)
{
eDBconn *dbc = NULL;
@@ -292,12 +498,27 @@ void eDBdisconnect(eurephiaCTX *ctx)
/**
+ * @copydoc eDBdisconnect_firewall()
+ */
+void eDBdisconnect_firewall(eurephiaCTX *ctx) {
+ DEBUG(ctx, 20, "Function call: eDBdisconnect_firewall(ctx)");
+ DEBUG(ctx, 21, "Closing PostgreSQL file descriptor (%ld) for firewall thread",
+ PQsocket(ctx->dbc->dbhandle));
+ /* Is there a better way how to avoid the firewall thread to close the inherited
+ * PostgreSQL connection? ... this is pretty brute force, but seems to work
+ */
+ close(PQsocket(ctx->dbc->dbhandle));
+ ctx->dbc->dbhandle = NULL;
+}
+
+
+/**
* @copydoc eDBauth_TLS()
*/
int eDBauth_TLS(eurephiaCTX *ctx, const char *org, const char *cname, const char *email,
const char *digest, const unsigned int depth)
{
- int certid = 0;
+ int certid = 0, prepid = -1;
PGresult *dbr = NULL;
char *blid = NULL;
char depth_str[5];
@@ -311,19 +532,20 @@ int eDBauth_TLS(eurephiaCTX *ctx, const char *org, const char *cname, const char
return 0;
}
- dbr = PQprepare(ctx->dbc->dbhandle, PREPSQL_TLS_AUTH,
- "SELECT cert.certid, blid "
- " FROM certificates cert"
- " LEFT JOIN blacklist bl USING(digest)"
- " WHERE organisation=$1::varchar AND common_name=$2::varchar "
- " AND email=$3::varchar AND depth=$4::varchar "
- " AND lower(cert.digest)=lower($5::varchar)\0",
- 5, NULL);
- if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_TLS_AUTH, "Failed to prepare SQL query");
+ prepid = ePGprepStatement(ctx, PREPSQL_TLS_AUTH,
+ "SELECT cert.certid, blid "
+ " FROM certificates cert"
+ " LEFT JOIN blacklist bl USING(digest)"
+ " WHERE organisation=$1::VARCHAR"
+ " AND common_name=$2::VARCHAR"
+ " AND email=$3::VARCHAR AND depth=$4::INTEGER"
+ " AND lower(cert.digest)=lower($5::VARCHAR)\0",
+ 5);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_TLS_AUTH,
+ "Failed to prepare SQL query");
return 0;
}
- PQclear(dbr);
// Check if certificate is valid, and not too many attempts has been tried with
// the given certificate
@@ -334,7 +556,7 @@ int eDBauth_TLS(eurephiaCTX *ctx, const char *org, const char *cname, const char
qry_args[2] = email;
qry_args[3] = depth_str;
qry_args[4] = digest;
- dbr = PQexecPrepared(ctx->dbc->dbhandle, PREPSQL_TLS_AUTH, 5, qry_args, NULL, NULL, 0);
+ dbr = ePGprepExec(ctx, prepid, qry_args);
free_nullsafe(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_TLS_AUTH,
@@ -369,7 +591,7 @@ int eDBauth_TLS(eurephiaCTX *ctx, const char *org, const char *cname, const char
*/
int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const char *passwd)
{
- int uicid = 0, pwdok = 0;
+ int uicid = 0, pwdok = 0, prepid = -1;
PGresult *dbr = NULL;
char certid_str[10];
char *crpwd = NULL, *activated = NULL, *deactivated = NULL;
@@ -384,35 +606,37 @@ int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const
return 0;
}
- dbr = PQprepare(ctx->dbc->dbhandle, PREPSQL_USERPWD_AUTH,
- "SELECT uicid, ou.uid, activated, deactivated, bl1.blid, bl2.blid, password "
- " FROM users ou"
- " JOIN usercerts uc USING(uid) "
- " LEFT JOIN blacklist bl1 ON( ou.username = bl1.username) "
- " LEFT JOIN (SELECT blid, certid "
- " FROM certificates "
- " JOIN blacklist USING(digest)) bl2 ON(uc.certid = bl2.certid)"
- " WHERE uc.certid = $1::INTEGER AND ou.username = $2::VARCHAR", 2, NULL);
- if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ prepid = ePGprepStatement(ctx, PREPSQL_USERPWD_AUTH,
+ "SELECT uicid, ou.uid, activated, deactivated,"
+ "bl1.blid, bl2.blid, password"
+ " FROM users ou"
+ " JOIN usercerts uc USING(uid)"
+ " LEFT JOIN blacklist bl1 ON( ou.username = bl1.username)"
+ " LEFT JOIN (SELECT blid, certid"
+ " FROM certificates"
+ " JOIN blacklist USING(digest)) bl2"
+ " ON(uc.certid = bl2.certid)"
+ " WHERE uc.certid = $1::INTEGER"
+ " AND ou.username = $2::VARCHAR", 2);
+ if( prepid < 0 ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_USERPWD_AUTH,
"Failed to prepare SQL query");
uicid = 0;
goto exit;
}
- PQclear(dbr);
-
// Look up the user in the database
snprintf(certid_str, 9, "%8i%c", certid, 0);
qry_args = calloc(2, sizeof(char *));
qry_args[0] = certid_str;
qry_args[1] = username;
- dbr = PQexecPrepared(ctx->dbc->dbhandle, PREPSQL_USERPWD_AUTH, 2, qry_args, NULL, NULL, 0);
+ dbr = ePGprepExec(ctx, prepid, qry_args);
free_nullsafe(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0,
- "Failed to lookup user account information [username=%s, certid=%s]",
- username, certid_str);
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_NONE,
+ "Failed to lookup user account information "
+ "[username=%s, certid=%s]",
+ username, certid_str);
uicid = 0;
goto exit;
}
@@ -470,30 +694,33 @@ int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const
uicid = -1;
} else {
PGresult *upd = NULL;
+ int prepid = -1;
uicid = atoi_nullsafe(ePGgetValue(dbr, 0, 0));
// Update last accessed status
- upd = PQprepare(ctx->dbc->dbhandle, PREPSQL_USERS_LASTACC_UPD,
- "UPDATE users SET last_accessed = CURRENT_TIMESTAMP"
- " WHERE uid = $1::INTEGER", 1, NULL);
- if( !dbr || (PQresultStatus(upd) != PGRES_COMMAND_OK) ) {
- ePGerrorMessage(ctx, upd, LOG_FATAL, 0, PREPSQL_USERS_LASTACC_UPD,
- "Failed to prepare SQL query");
- } else if( dbr ) {
+ prepid = ePGprepStatement(ctx, PREPSQL_USERS_LASTACC_UPD,
+ "UPDATE users_last_access SET last_accessed = NULL"
+ " WHERE uid = $1::INTEGER", 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_USERS_LASTACC_UPD,
+ "Failed to prepare SQL query");
+ } else {
PQclear(upd);
qry_args = calloc(1, sizeof(char *));
qry_args[0] = uid;
- upd = PQexecPrepared(ctx->dbc->dbhandle, PREPSQL_USERS_LASTACC_UPD,
- 1, qry_args, NULL, NULL, 0);
+ upd = ePGprepExec(ctx, prepid, qry_args);
free_nullsafe(ctx, qry_args);
- if( !upd || (PQresultStatus(upd) != PGRES_TUPLES_OK) ) {
- ePGerrorMessage(ctx, upd, LOG_FATAL, 0, PREPSQL_USERS_LASTACC_UPD
- "Failed to update last access status for uid %s", uid);
- }
- if( upd ) {
- PQclear(upd);
+ if( !upd || (PQresultStatus(upd) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, upd, LOG_FATAL, 0,
+ PREPSQL_USERS_LASTACC_UPD,
+ "Failed to update last access status "
+ "for uid %s", uid);
+ } else {
+ if( upd ) {
+ PQclear(upd);
+ }
}
}
}
@@ -514,7 +741,7 @@ int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const
*/
int eDBget_uid(eurephiaCTX *ctx, const int certid, const char *username)
{
- int ret = 0;
+ int ret = 0, prepid = -1;
PGresult *dbr = NULL;
const char **qry_args = NULL;
char certid_str[10];
@@ -526,34 +753,33 @@ int eDBget_uid(eurephiaCTX *ctx, const int certid, const char *username)
return 0;
}
- dbr = PQprepare(ctx->dbc->dbhandle, PREPSQL_USERS_GETUID,
- "SELECT uid "
- " FROM usercerts "
- " JOIN users USING (uid) "
- " WHERE certid = $1::INTEGER AND username = $1::VARCHAR",
- 2, NULL);
- if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ prepid = ePGprepStatement(ctx, PREPSQL_USERS_GETUID,
+ "SELECT uid "
+ " FROM usercerts "
+ " JOIN users USING (uid) "
+ " WHERE certid = $1::INTEGER AND username = $2::VARCHAR",
+ 2);
+ if( prepid < 0 ) {
ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_USERS_GETUID,
- "Failed to prepare SQL query");
+ "Failed to prepare SQL query");
ret = -1;
goto exit;
}
- PQclear(dbr);
snprintf(certid_str, 9, "%8i%c", certid, 0);
qry_args = calloc(2, sizeof(char *));
qry_args[0] = certid_str;
qry_args[1] = username;
- dbr = PQexecPrepared(ctx->dbc->dbhandle, PREPSQL_USERPWD_AUTH, 2, qry_args, NULL, NULL, 0);
+ dbr = ePGprepExec(ctx, prepid, qry_args);
free_nullsafe(ctx, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_USERPWD_AUTH,
- "Failed to lookup userid for user '%s'", username);
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_USERS_GETUID,
+ "Failed to lookup userid for user '%s'", username);
ret = -1;
goto exit;
}
- switch( PQntuples(dbr) > 1 ) {
+ switch(PQntuples(dbr)) {
case 0:
eurephia_log(ctx, LOG_WARNING,0, "Failed to find userid for certid %i and username '%s'",
certid, username);
@@ -584,135 +810,102 @@ int eDBget_uid(eurephiaCTX *ctx, const int certid, const char *username)
*/
int eDBblacklist_check(eurephiaCTX *ctx, const int type, const char *val)
{
- int blacklisted = 0;
+ int blacklisted = 0, prepid = -1;
char sql[4098], *blid = NULL;
const char **qry_args = NULL;
PGresult *dbr = NULL;
+ const eDBattempt_types_t *atmptype = &eDBattempt_types[type];
DEBUG(ctx, 20, "Function call: eDBblacklist_check(ctx, '%s', '%s')",
- eDBattempt_types[type].descr, val);
+ atmptype->descr, val);
- qry_args = calloc(1, sizeof(char *));
- qry_args[0] = val;
+ qry_args = calloc(1, sizeof(char *));
+ qry_args[0] = val;
snprintf(sql, 4096,
- "SELECT blid"
- " FROM blacklist"
- " WHERE %s = %s%s$1%s",
- eDBattempt_types[type].colname_where,
- defaultValue(eDBattempt_types[type].value_func, ""),
- (eDBattempt_types[type].value_func ? "(" : ""),
- (eDBattempt_types[type].value_func ? ")" : ""));
-
- dbr = PQprepare(ctx->dbc->dbhandle, PREPSQL_BLACKLIST_CHECK, sql, 1, NULL);
- if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_BLACKLIST_CHECK,
+ "SELECT atpid, attempts >= %s, blid, attempts "
+ " FROM attempts "
+ " LEFT JOIN blacklist USING(%s)"
+ " WHERE %s = %s%s$1::VARCHAR%s",
+ defaultValue(eGet_value(ctx->dbc->config, atmptype->allow_cfg),
+ atmptype->default_value),
+ atmptype->colname, atmptype->colname_where,
+ defaultValue(atmptype->value_func, ""),
+ (atmptype->value_func ? "(" : ""),
+ (atmptype->value_func ? ")" : ""));
+
+ prepid = ePGprepStatement(ctx, atmptype->sql_blacklist_check, sql, 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_blacklist_check,
"Failed to prepare SQL query");
blacklisted = -1;
- goto exit;
+ goto error;
}
- PQclear(dbr);
-
- dbr = PQexecPrepared(ctx->dbc->dbhandle, PREPSQL_BLACKLIST_CHECK, 2, qry_args, NULL, NULL, 0);
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_BLACKLIST_CHECK,
- "Failed to lookup %s in the blacklist for '%s'",
- eDBattempt_types[type].descr, val);
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, atmptype->sql_blacklist_check,
+ "Failed to lookup %s in the attempts/blacklist table for '%s'",
+ atmptype->descr, val);
blacklisted = -1;
- goto exit;
+ goto error;
}
if( dbr && PQntuples(dbr) > 0 ) {
- blid = ePGgetValue(dbr, 0, 0);
+ char *atpid = NULL;
+ int atpexceed = -1, atpcount = 0;
+
+ blid = ePGgetValue(dbr, 0, 2);
if( blid != NULL ) {
eurephia_log(ctx, LOG_WARNING, 0, "Attempt from blacklisted %s: %s",
- eDBattempt_types[type].descr, val);
+ atmptype->descr, val);
blacklisted = 1; // [type] is blacklisted
- }
- update_blacklist_attempt(ctx, blid);
- PQclear(dbr);
- } else {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_BLACKLIST_CHECK,
- "Blacklist query for %s failed (%s)",
- eDBattempt_types[type].descr, val);
- };
-
- // Check if this [type] have been tried before and consider if it should be blacklisted
- if( blacklisted == 0) {
- char *atpid = NULL;
- int atpexceed = -1;
-
- snprintf(sql, 4096,
- "SELECT atpid, attempts >= '%s' "
- " FROM attempts "
- " WHERE %s = $1",
- defaultValue(eGet_value(ctx->dbc->config, eDBattempt_types[type].allow_cfg),
- eDBattempt_types[type].default_value),
- eDBattempt_types[type].colname_where);
- dbr = PQprepare(ctx->dbc->dbhandle, PREPSQL_ATTEMPTS_CHECK, sql, 1, NULL);
- if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_ATTEMPTS_CHECK,
- "Failed to prepare SQL query");
- blacklisted = -1;
- goto exit;
- }
- PQclear(dbr);
-
- dbr = PQexecPrepared(ctx->dbc->dbhandle, PREPSQL_BLACKLIST_CHECK, 1, qry_args, NULL, NULL, 0);
- if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_BLACKLIST_CHECK,
- "Failed look up attempts counter for %s in the blacklist check on '%s'",
- eDBattempt_types[type].descr, val);
- blacklisted = -1;
+ update_blacklist_attempt(ctx, blid);
goto exit;
}
- if( dbr && (PQntuples(dbr) > 0) ) {
- atpid = ePGgetValue(dbr, 0, 0);
- atpexceed = atoi_nullsafe(ePGgetValue(dbr, 0, 1));
-
- // If [type] has reached attempt limit and it is not black listed, black list it
- if( (atpexceed > 0) && (blid == NULL) ) {
- PGresult *blr = NULL;
-
- eurephia_log(ctx, LOG_WARNING, 0,
- "%s got BLACKLISTED due to too many failed attempts: %s",
- eDBattempt_types[type].descr, val);
-
- snprintf(sql, 4096, "INSERT INTO blacklist (%s) VALUES ($1)",
- eDBattempt_types[type].colname);
- blr = PQprepare(ctx->dbc->dbhandle, PREPSQL_BLACKLIST_REGISTER, sql, 1, NULL);
- if( !blr || (PQresultStatus(blr) != PGRES_COMMAND_OK) ) {
- ePGerrorMessage(ctx, blr, LOG_FATAL, 0, PREPSQL_BLACKLIST_REGISTER,
- "Failed to prepare SQL query");
- } else {
- PQclear(blr);
- blr = PQexecPrepared(ctx->dbc->dbhandle,
- PREPSQL_BLACKLIST_REGISTER, 1, qry_args,
- NULL, NULL, 0);
- if( !blr || (PQresultStatus(blr) != PGRES_COMMAND_OK) ) {
- ePGerrorMessage(ctx, blr, LOG_FATAL, 0,
- PREPSQL_BLACKLIST_REGISTER,
- "Failed to register %s value '%s' in the "
- "blacklist:",
- eDBattempt_types[type].descr, val);
- }
+ // Check if this [type] have been tried before and consider if it should be blacklisted
+ atpid = ePGgetValue(dbr, 0, 0);
+ atpexceed = atoi_nullsafe(ePGgetValue(dbr, 0, 1));
+ atpcount = atoi_nullsafe(ePGgetValue(dbr, 0, 3));
+
+ // If [type] has reached attempt limit and it is not black listed, black list it
+ if( (atpexceed > 0) && (blid == NULL) ) {
+ PGresult *blr = NULL;
+
+ eurephia_log(ctx, LOG_WARNING, 0,
+ "%s got BLACKLISTED due to too many (%i) failed attempts: %s",
+ atmptype->descr, atpcount, val);
+
+ snprintf(sql, 4096, "INSERT INTO blacklist (%s) VALUES ($1)",
+ atmptype->colname);
+ prepid = ePGprepStatement(ctx, atmptype->sql_blacklist_reg, sql, 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_blacklist_reg,
+ "Failed to prepare SQL query");
+ } else {
+ blr = ePGprepExec(ctx, prepid, qry_args);
+ if( !blr
+ || (PQresultStatus(blr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, blr, LOG_FATAL, 0,
+ atmptype->sql_blacklist_reg,
+ "Failed to register %s value "
+ "'%s' in the blacklist:",
+ atmptype->descr,
+ val);
}
PQclear(blr);
- blacklisted = 1; // [type] is blacklisted
}
- atpid = NULL;
- PQclear(dbr);
- } else {
- ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_BLACKLIST_CHECK,
- "Querying attempts counts for blacklisted %s failed (%s)",
- eDBattempt_types[type].descr, val);
+ blacklisted = 1; // [type] is blacklisted
}
+ atpid = NULL;
+ PQclear(dbr);
}
+ exit:
DEBUG(ctx, 20, "Result - function call: eDBblacklist_check(ctx, '%s', '%s') - %i",
- eDBattempt_types[type].descr, val, blacklisted);
+ atmptype->descr, val, blacklisted);
- exit:
+ error:
blid = NULL;
free_nullsafe(ctx, qry_args);
@@ -725,26 +918,159 @@ int eDBblacklist_check(eurephiaCTX *ctx, const int type, const char *val)
*/
void eDBregister_attempt(eurephiaCTX *ctx, int type, int mode, const char *value)
{
+ const eDBattempt_types_t *atmptype = &eDBattempt_types[type];
+ const char **qry_args = NULL;
+ char sql[4098];
+ char *id = NULL, *atmpt_block = NULL, *blid = NULL;
+ int prepid = -1, attempts = 0;
+ PGresult *dbr = NULL;
+
DEBUG(ctx, 20, "Function call: eDBregister_attempt(ctx, %s, %s, '%s')",
- eDBattempt_types[type].colname,
+ atmptype->colname,
(mode == ATTEMPT_RESET ? "ATTEMPT_RESET" : "ATTEMPT_REGISTER"),
value);
- /*
- "SELECT atpid, attempts > %s, blid, attempts "
- " FROM attempts "
- " LEFT JOIN blacklist USING(%s)"
- " WHERE %s = %s%s'%q'%s",
- defaultValue(eGet_value(ctx->dbc->config, eDBattempt_types[type].allow_cfg),
- eDBattempt_types[type].default_value),
- eDBattempt_types[type].colname,
- eDBattempt_types[type].colname_where,
- defaultValue(eDBattempt_types[type].value_func, ""),
- (strlen_nullsafe(eDBattempt_types[type].value_func) > 0 ? "(" : ""),
- value,
- (strlen_nullsafe(eDBattempt_types[type].value_func) > 0 ? ")" : "")
- );
- */
+ qry_args = calloc(1, sizeof(char *));
+ qry_args[0] = value;
+
+ snprintf(sql, 4096,
+ "SELECT atpid, attempts > %s, blid, attempts "
+ " FROM attempts "
+ " LEFT JOIN blacklist USING(%s)"
+ " WHERE %s = %s%s$1::VARCHAR%s",
+ defaultValue(eGet_value(ctx->dbc->config, atmptype->allow_cfg),
+ atmptype->default_value),
+ atmptype->colname, atmptype->colname_where,
+ defaultValue(atmptype->value_func, ""),
+ (atmptype->value_func ? "(" : ""),
+ (atmptype->value_func ? ")" : ""));
+ prepid = ePGprepStatement(ctx, atmptype->sql_blacklist_check, sql, 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_blacklist_check,
+ "Failed to prepare SQL query");
+ }
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, atmptype->sql_blacklist_check,
+ "Failed to lookup %s in the attempts/blacklist table for '%s'",
+ atmptype->descr, value);
+ return;
+ }
+
+ attempts = atoi_nullsafe(ePGgetValue(dbr, 0, 3));
+ // If we are asked to reset the attempt counter and we do not find any attempts, exit here
+ if( (mode == ATTEMPT_RESET) && ((PQntuples(dbr) == 0) || (attempts == 0))) {
+ PQclear(dbr);
+ return;
+ }
+
+ id = strdup_nullsafe(ePGgetValue(dbr, 0, 0));
+ atmpt_block = strdup_nullsafe(ePGgetValue(dbr, 0, 1));
+ blid = strdup_nullsafe(ePGgetValue(dbr, 0, 2));
+ PQclear(dbr);
+
+ if( (id == NULL) && (mode == ATTEMPT_REGISTER) ) {
+ // Only insert record when we are in registering mode
+ snprintf(sql, 4096, "INSERT INTO attempts (%s, attempts) VALUES ($1::VARCHAR, 1)",
+ atmptype->colname);
+ prepid = ePGprepStatement(ctx, atmptype->sql_attempts_reg, sql, 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_attempts_reg,
+ "Failed to prepare SQL query");
+ goto error;
+ }
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_attempts_reg,
+ "Failed to register failed attempt for %s '%s'",
+ atmptype->descr, value);
+ goto error;
+ }
+ PQclear(dbr);
+ } else if( id != NULL ){
+ // if a attempt record exists, update it according to mode
+ qry_args[0] = id;
+ switch( mode ) {
+ case ATTEMPT_RESET:
+ prepid = ePGprepStatement(ctx, PREPSQL_ATTEMPTS_RESET,
+ "UPDATE attempts"
+ " SET attempts = 0 "
+ " WHERE atpid = $1::INTEGER", 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_ATTEMPTS_RESET,
+ "Failed to prepare SQL query");
+ goto error;
+ }
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_ATTEMPTS_RESET,
+ "Failed to reset attempts counter for atpid '%s' (%s %s)",
+ id, atmptype->descr, value);
+ goto error;
+ }
+ PQclear(dbr);
+ break;
+ default:
+ prepid = ePGprepStatement(ctx, PREPSQL_ATTEMPTS_INCR,
+ "UPDATE attempts"
+ " SET last_attempt = CURRENT_TIMESTAMP, "
+ " attempts = attempts + 1"
+ " WHERE atpid = $1::INTEGER", 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_ATTEMPTS_INCR,
+ "Failed to prepare SQL query");
+ goto error;
+ }
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_ATTEMPTS_INCR,
+ "Failed to increment attempts counter for atpid '%s' (%s %s)",
+ id, atmptype->descr, value);
+ goto error;
+ }
+ PQclear(dbr);
+ break;
+ }
+ }
+
+ // If attempts have exceeded attempt limit, blacklist it immediately if not already registered
+ if( (mode == ATTEMPT_REGISTER)
+ && (blid == NULL) && (atmpt_block != NULL) && (atmpt_block[0] == 't') ) {
+ eurephia_log(ctx, LOG_WARNING, 0, "Blacklisting %s due to too many attempts: %s",
+ eDBattempt_types[type].descr, value);
+
+ snprintf(sql, 4096, "INSERT INTO blacklist (%s) VALUES ($1)",
+ atmptype->colname);
+ prepid = ePGprepStatement(ctx, atmptype->sql_blacklist_reg, sql, 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, atmptype->sql_blacklist_reg,
+ "Failed to prepare SQL query");
+ } else {
+ qry_args[0] = value;
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr
+ || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0,
+ atmptype->sql_blacklist_reg,
+ "Failed to blacklist %s value "
+ "'%s':",
+ atmptype->descr,
+ value);
+ goto error;
+ }
+ PQclear(dbr);
+ }
+ }
+
+ error:
+ free_nullsafe(ctx, id);
+ free_nullsafe(ctx, atmpt_block);
+ free_nullsafe(ctx, blid);
+
}
/**
@@ -754,18 +1080,51 @@ int eDBregister_login(eurephiaCTX *ctx, eurephiaSESSION *skey, const int certid,
const char *proto, const char *remipaddr, const char *remport,
const char *vpnipaddr, const char *vpnipmask)
{
+ char uidstr[10], certidstr[10];
+ const char **qry_args = NULL;
+ int prepid = -1, ret = 0;
+ PGresult *dbr = NULL;
+
DEBUG(ctx, 20, "Function call: eDBregister_login(ctx, '%s', %i, %i, '%s','%s','%s','%s','%s')",
skey->sessionkey, certid, uid, proto, remipaddr, remport, vpnipaddr, vpnipmask);
- /*
- "INSERT INTO lastlog (uid, certid, "
- " protocol, remotehost, remoteport,"
- " vpnipaddr, vpnipmask,"
- " sessionstatus, sessionkey, login) "
- "VALUES (%i, %i, '%q','%q','%q','%q','%q', 1,'%q', CURRENT_TIMESTAMP)",
- uid, certid, proto, remipaddr, remport, vpnipaddr, vpnipmask, skey->sessionke
- */
- return 0;
+ prepid = ePGprepStatement(ctx, PREPSQL_REGISTER_LOGIN,
+ "INSERT INTO lastlog (uid, certid, "
+ " protocol, remotehost, remoteport,"
+ " vpnipaddr, vpnipmask,"
+ " sessionstatus, sessionkey, login) "
+ "VALUES ($1::INTEGER, $2::INTEGER, "
+ " $3::VARCHAR, $4::VARCHAR, $5::INTEGER,"
+ " $6::VARCHAR, $7::VARCHAR,"
+ " 1, $8::VARCHAR, CURRENT_TIMESTAMP)", 8);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_REGISTER_LOGIN,
+ "Failed to prepare query");
+ return 0;
+ }
+
+ qry_args = calloc(8, sizeof(char *));
+ snprintf(uidstr, 8, "%i", uid); qry_args[0] = uidstr;
+ snprintf(certidstr, 8, "%i", certid); qry_args[1] = certidstr;
+ qry_args[2] = proto;
+ qry_args[3] = remipaddr;
+ qry_args[4] = remport;
+ qry_args[5] = vpnipaddr;
+ qry_args[6] = vpnipmask;
+ qry_args[7] = skey->sessionkey;
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ free_nullsafe(ctx, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0, PREPSQL_REGISTER_LOGIN,
+ "Failed to register session login for session key '%s'",
+ skey->sessionkey);
+ ret = 0;
+ } else {
+ ret = 1;
+ PQclear(dbr);
+ }
+ return ret;
}
@@ -774,17 +1133,63 @@ int eDBregister_login(eurephiaCTX *ctx, eurephiaSESSION *skey, const int certid,
*/
int eDBregister_vpnmacaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const char *macaddr)
{
+ const char **qry_args = NULL;
+ int prepid_reg = -1, prepid_ll = -1, ret = 0;
+ PGresult *dbr = NULL;
+
DEBUG(ctx, 20, "Function call: eDBregister_vpnmacaddr(ctx, '%s', '%s')",
session->sessionkey, macaddr);
- /*
- "INSERT INTO macaddr_history (sessionkey, macaddr) VALUES ('%q','%q')",
- session->sessionkey, macaddr);
+ /* TODO: Use transaction */
+
+ prepid_reg = ePGprepStatement(ctx, PREPSQL_MACHISTORY_REGISTER,
+ "INSERT INTO macaddr_history (sessionkey, macaddr)"
+ " VALUES ($1::VARCHAR, $2::VARCHAR)", 2);
+ if( prepid_reg < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_MACHISTORY_REGISTER,
+ "Failed to prepare SQL query");
+ return 0;
+ }
+
+ prepid_ll = ePGprepStatement(ctx, PREPSQL_MACHISTORY_LASTLOG,
+ "UPDATE lastlog_update "
+ " SET sessionstatus = 2,macaddr = $2::VARCHAR"
+ " WHERE sessionkey = $1::VARCHAR AND sessionstatus = 1", 2);
+ if( prepid_ll < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_MACHISTORY_LASTLOG,
+ "Failed to prepare SQL query");
+ return 0;
+ }
- "UPDATE lastlog SET sessionstatus = 2, macaddr = '%q' "
- " WHERE sessionkey = '%q' AND sessionstatus = 1", macaddr, session->sessionkey);
+ qry_args = calloc(2, sizeof(const char *));
+ qry_args[0] = session->sessionkey;
+ qry_args[1] = macaddr;
- */
+ // Register the MAC address into the macaddr_history table
+ dbr = ePGprepExec(ctx, prepid_reg, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0,
+ PREPSQL_MACHISTORY_REGISTER,
+ "eDBregister_vpnmacaddr: Failed to register VPN client "
+ "MAC address (%s/%s)",
+ session->sessionkey, macaddr);
+ ret = 0;
+ goto exit;
+ }
+ PQclear(dbr);
+
+ // Update lastlog table with the latest used MAC address
+ dbr = ePGprepExec(ctx, prepid_ll, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0,
+ PREPSQL_MACHISTORY_LASTLOG,
+ "eDBregister_vpnmacaddr: Failed to update "
+ "lastlog with MAC address info (%s/%s)",
+ session->sessionkey, macaddr);
+ ret = 0;
+ goto exit;
+ }
+ PQclear(dbr);
// Save the MAC address in the session values register - needed for the destroy session
if( eDBset_session_value(ctx, session, "macaddr", macaddr) == 0 ) {
@@ -792,6 +1197,8 @@ int eDBregister_vpnmacaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const cha
return 0;
}
+ exit:
+ free_nullsafe(ctx, qry_args);
return 1;
}
@@ -802,18 +1209,40 @@ int eDBregister_vpnmacaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const cha
int eDBregister_logout(eurephiaCTX *ctx, eurephiaSESSION *skey,
const char *bytes_sent, const char *bytes_received, const char *duration)
{
+ const char **qry_args = NULL;
+ int prepid = -1;
+ PGresult *dbr = NULL;
+
DEBUG(ctx, 20, "Function call: eDBregister_logout(ctx, '%s', %s, %s)",
skey->sessionkey, bytes_sent, bytes_received);
- /*
- "UPDATE lastlog "
- " SET sessionstatus = 3, logout = CURRENT_TIMESTAMP, "
- " bytes_sent = '%i', bytes_received = '%i', session_duration = '%i' "
- " WHERE sessionkey = '%q' AND sessionstatus = 2",
- atoi_nullsafe(bytes_sent), atoi_nullsafe(bytes_received),
- atoi_nullsafe(duration), skey->sessionkey);
- */
+ prepid = ePGprepStatement(ctx, PREPSQL_REGISTER_LOGOUT,
+ "UPDATE lastlog_update "
+ " SET sessionstatus = 3, logout = CURRENT_TIMESTAMP, "
+ " bytes_sent=$2::INTEGER, bytes_received=$3::INTEGER,"
+ " session_duration = $4::INTERVAL "
+ " WHERE sessionkey = $1::VARCHAR AND sessionstatus = 2", 4);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_REGISTER_LOGOUT,
+ "Failed to prepare SQL query");
+ }
+
+ qry_args = calloc(4, sizeof(char *));
+ qry_args[0] = skey->sessionkey;
+ qry_args[1] = bytes_sent;
+ qry_args[2] = bytes_received;
+ qry_args[3] = duration;
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0, PREPSQL_REGISTER_LOGOUT,
+ "Failed to lastlog with logout info (%s)",
+ skey->sessionkey);
+ free_nullsafe(ctx, qry_args);
+ return 0;
+ }
+ PQclear(dbr);
+ free_nullsafe(ctx, qry_args);
skey->sessionstatus = SESSION_LOGGEDOUT;
return 1;
}
@@ -824,7 +1253,11 @@ int eDBregister_logout(eurephiaCTX *ctx, eurephiaSESSION *skey,
*/
char *eDBget_sessionkey_seed(eurephiaCTX *ctx, sessionType type, const char *sessionseed)
{
+ const char **qry_args = NULL;
char *skey = NULL;
+ _ePG_prepID preptype = PREPSQL_NONE;
+ int prepid = -1;
+ PGresult *dbr = NULL;
DEBUG(ctx, 20, "eDBget_sessionkey_seed(ctx, %i, '%s')", type, sessionseed);
@@ -834,35 +1267,57 @@ char *eDBget_sessionkey_seed(eurephiaCTX *ctx, sessionType type, const char *ses
return NULL;
}
+ qry_args = calloc(1, sizeof(char *));
+ qry_args[0] = sessionseed;
+
switch( type ) {
case stSESSION:
- /*
- "SELECT sessionkey "
- " FROM sessionkeys "
- " JOIN lastlog USING (sessionkey)"
- " WHERE sessionstatus IN (1,2)"
- " AND sessionseed = '%q'",
- sessionseed);
- */
+ preptype = PREPSQL_SESSIONKEY_GETSEED_SESSION;
+ prepid = ePGprepStatement(ctx, preptype,
+ "SELECT sessionkey "
+ " FROM sessionkeys "
+ " JOIN lastlog USING (sessionkey)"
+ " WHERE sessionstatus IN (1,2)"
+ " AND sessionseed = $1::VARCHAR", 1);
break;
case stAUTHENTICATION:
- /*
- "SELECT sessionkey"
- " FROM sessionkeys"
- " LEFT JOIN lastlog USING(sessionkey)"
- " WHERE sessionstatus IS NULL"
- " AND sessionseed = '%q'",
- sessionseed);
- */
+ preptype = PREPSQL_SESSIONKEY_GETSEED_AUTH;
+ prepid = ePGprepStatement(ctx, preptype,
+ "SELECT sessionkey "
+ " FROM sessionkeys "
+ " LEFT JOIN lastlog USING (sessionkey)"
+ " WHERE sessionstatus IS NULL"
+ " AND sessionseed = $1::VARCHAR", 1);
break;
default:
eurephia_log(ctx, LOG_ERROR, 0, "Invalid session type: %i", type);
- return NULL;
+ goto exit;
+ }
+
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, preptype,
+ "Failed to prepare SQL query");
+ skey = NULL;
+ goto exit;
+ }
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, preptype,
+ "Failed to lookup session key from session seed '%s'",
+ sessionseed);
+ skey = NULL;
+ goto exit;
}
+ skey = (PQntuples(dbr) == 1 ? strdup_nullsafe(PQgetvalue(dbr, 0, 0)) : NULL);
+ PQclear(dbr);
+ exit:
+ free_nullsafe(ctx, qry_args);
return skey;
+
}
@@ -872,19 +1327,43 @@ char *eDBget_sessionkey_seed(eurephiaCTX *ctx, sessionType type, const char *ses
char *eDBget_sessionkey_macaddr(eurephiaCTX *ctx, const char *macaddr)
{
char *skey = NULL;
+ const char **qry_args = NULL;
+ int prepid = -1;
+ PGresult *dbr = NULL;
+
DEBUG(ctx, 20, "eDBget_sessionkey_macaddr(ctx, '%s')", macaddr);
// Find sessionkey from MAC address
- /*
- "SELECT sessionkey "
- " FROM sessions "
- " JOIN lastlog USING (sessionkey)"
- " WHERE sessionstatus = 3 "
- " AND datakey = 'macaddr'"
- " AND dataval = '%q'", macaddr);
- */
+ prepid = ePGprepStatement(ctx, PREPSQL_SESSIONKEY_GETMAC,
+ "SELECT sessionkey "
+ " FROM sessions "
+ " JOIN lastlog USING (sessionkey)"
+ " WHERE sessionstatus = 3 "
+ " AND datakey = 'macaddr'"
+ " AND dataval = $1::VARCHAR", 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_SESSIONKEY_GETMAC,
+ "Failed to prepare SQL query");
+ return NULL;
+ }
+ qry_args = calloc(1, sizeof(char *));
+ qry_args[0] = macaddr;
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_SESSIONKEY_GETMAC,
+ "Failed to lookup session key from MAC address '%s'",
+ macaddr);
+ skey = NULL;
+ goto exit;
+ }
+ skey = (PQntuples(dbr) == 1 ? strdup_nullsafe(PQgetvalue(dbr, 0, 0)) : NULL);
+ PQclear(dbr);
+
+ exit:
+ free_nullsafe(ctx, qry_args);
return skey;
}
@@ -895,8 +1374,13 @@ char *eDBget_sessionkey_macaddr(eurephiaCTX *ctx, const char *macaddr)
int eDBcheck_sessionkey_uniqueness(eurephiaCTX *ctx, const char *seskey)
{
int uniq = 0;
+ const char **qry_args = NULL;
+ int prepid = -1;
+ _ePG_prepID preptype;
+ PGresult *dbr = NULL;
DEBUG(ctx, 20, "eDBcheck_sessionkey_uniqueness(ctx, '%s')", seskey);
+
if( seskey == NULL ) {
eurephia_log(ctx, LOG_FATAL, 1,
"eDBcheck_sessionkey_uniqness: Invalid session key given");
@@ -910,22 +1394,46 @@ int eDBcheck_sessionkey_uniqueness(eurephiaCTX *ctx, const char *seskey)
case ECTX_ADMIN_CONSOLE:
case ECTX_ADMIN_WEB:
- /*
- "SELECT count(sessionkey) = 0 "
- "FROM eurephia_adminlog WHERE sessionkey = '%q'", seskey);
- */
+ preptype = PREPSQL_SESSIONKEY_UNIQ_ADMIN;
+ prepid = ePGprepStatement(ctx, preptype,
+ "SELECT count(sessionkey) = 0 "
+ "FROM eurephia_adminlog WHERE sessionkey = $1::VARCHAR", 1);
break;
case ECTX_PLUGIN_AUTH:
default:
- /*
- "SELECT count(sessionkey) = 0 "
- "FROM lastlog WHERE sessionkey = '%q'", seskey);
- */
+ preptype = PREPSQL_SESSIONKEY_UNIQ_PLAUTH;
+ prepid = ePGprepStatement(ctx, preptype,
+ "SELECT count(sessionkey) = 0 "
+ "FROM lastlog WHERE sessionkey = $1::VARCHAR", 1);
break;
}
- return uniq;
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, preptype,
+ "Failed to prepare SQL query");
+ return 0;
+ }
+
+ qry_args = calloc(1, sizeof(char *));
+ qry_args[0] = seskey;
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, preptype,
+ "Failed to check session key uniqueness for '%s'",
+ seskey);
+ uniq = 0;
+ goto exit;
+ } else if( PQntuples(dbr) == 1 ) {
+ char *res = PQgetvalue(dbr, 0, 0);
+ uniq = (*res == 't');
+ }
+ PQclear(dbr);
+
+ exit:
+ free_nullsafe(ctx, qry_args);
+ return uniq;
}
@@ -933,7 +1441,9 @@ int eDBcheck_sessionkey_uniqueness(eurephiaCTX *ctx, const char *seskey)
* @copydoc eDBregister_sessionkey()
*/
int eDBregister_sessionkey(eurephiaCTX *ctx, const char *seed, const char *seskey) {
- // dbresult *res;
+ const char **qry_args = NULL;
+ int prepid = -1, ret = 0;
+ PGresult *dbr = NULL;
DEBUG(ctx, 20, "eDBregister_sessionkey(ctx, '%s', '%s')", seed, seskey);
if( (seed == NULL) || (seskey == NULL) ) {
@@ -942,16 +1452,32 @@ int eDBregister_sessionkey(eurephiaCTX *ctx, const char *seed, const char *seske
return 0;
}
- /*
- * "INSERT INTO openvpn_sessionkeys (sessionseed, sessionkey) VALUES('%q','%q')",
-
- if( res == NULL ) {
- eurephia_log(ctx, LOG_FATAL, 0,
- "eDBregister_sessionkey: Error registering sessionkey into 'sessionkeys'");
+ prepid = ePGprepStatement(ctx, PREPSQL_SESSIONKEY_REGISTER,
+ "INSERT INTO sessionkeys (sessionseed, sessionkey) "
+ " VALUES($1::VARCHAR, $2::VARCHAR)", 2);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_SESSIONKEY_REGISTER,
+ "Failed to prepare SQL query");
return 0;
}
- */
- return 1;
+
+ qry_args = calloc(2, sizeof(char *));
+ qry_args[0] = seed;
+ qry_args[1] = seskey;
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_SESSIONKEY_REGISTER,
+ "eDBregister_sessionkey: Error registering sessionkey"
+ " into 'sessionkeys'");
+ ret = 0;
+ goto exit;
+ }
+ PQclear(dbr);
+ ret = 1;
+ exit:
+ free_nullsafe(ctx, qry_args);
+ return ret;
}
/**
@@ -964,7 +1490,9 @@ int eDBregister_sessionkey(eurephiaCTX *ctx, const char *seed, const char *seske
*
*/
int eDBremove_sessionkey(eurephiaCTX *ctx, const char *seskey) {
- // dbresult *res;
+ const char **qry_args = NULL;
+ int prepid = -1, ret = 0;
+ PGresult *dbr = NULL;
DEBUG(ctx, 20, "eDBremove_sessionkey(ctx, '%s')", seskey);
if( seskey == NULL ) {
@@ -973,35 +1501,84 @@ int eDBremove_sessionkey(eurephiaCTX *ctx, const char *seskey) {
return 0;
}
- /*
- * "DELETE FROM openvpn_sessionkeys WHERE sessionkey = '%q'", seskey);
- if( res == NULL ) {
- eurephia_log(ctx, LOG_FATAL, 0,
- "eDBremove_sessionkey: Error removing sessionkey from openvpn_sessionkeys");
+ prepid = ePGprepStatement(ctx, PREPSQL_SESSIONKEY_REMOVE,
+ "DELETE FROM sessionkeys WHERE sessionkey = $1::VARCHAR", 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_SESSIONKEY_REMOVE,
+ "Failed to prepare SQL query");
return 0;
}
- */
- return 1;
+
+ qry_args = calloc(1, sizeof(char *));
+ qry_args[0] = seskey;
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_SESSIONKEY_REMOVE,
+ "eDBremove_sessionkey: Error removing sessionkey '%s'",
+ seskey);
+ ret = 0;
+ goto exit;
+ }
+ PQclear(dbr);
+ ret = 1;
+ exit:
+ free_nullsafe(ctx, qry_args);
+ return ret;
}
/**
* @copydoc eDBload_sessiondata()
*/
-eurephiaVALUES *eDBload_sessiondata(eurephiaCTX *ctx, const char *sesskey)
+eurephiaVALUES *eDBload_sessiondata(eurephiaCTX *ctx, const char *seskey)
{
eurephiaVALUES *sessvals = NULL;
+ const char **qry_args = NULL;
+ int prepid = -1, i = 0;
+ PGresult *dbr = NULL;
+ DEBUG(ctx, 20, "Function call: eDBload_sessiondata(ctx, '%s')", seskey);
- DEBUG(ctx, 20, "Function call: eDBload_sessiondata(ctx, '%s')", sesskey);
+ prepid = ePGprepStatement(ctx, PREPSQL_SESSIONVARS_LOAD,
+ "SELECT datakey, dataval"
+ " FROM sessions"
+ " WHERE sessionkey = $1::VARCHAR", 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_SESSIONVARS_LOAD,
+ "Failed to prepare SQL query");
+ return NULL;
+ }
+
+ qry_args = calloc(1, sizeof(char *));
+ qry_args[0] = seskey;
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_SESSIONVARS_LOAD,
+ "eDBload_sessiondata: Failed to load session variables for session '%s'",
+ seskey);
+ sessvals = NULL;
+ goto exit;
+ }
sessvals = eCreate_value_space(ctx, 10);
+ if( !sessvals ) {
+ eurephia_log(ctx, LOG_CRITICAL, 0,
+ "Failed to create value storage for session variables for session '%s'",
+ seskey);
+ goto exit;
+ }
- /*
- "SELECT datakey, dataval FROM sessions WHERE sessionkey = '%q'",
- sesskey
- */
+ for( i = 0; i < PQntuples(dbr); i++ ) {
+ eAdd_value(ctx, sessvals,
+ ePGgetValue(dbr, i, 0),
+ ePGgetValue(dbr, i, 1));
+ }
+ PQclear(dbr);
+ exit:
+ free_nullsafe(ctx, qry_args);
return sessvals;
}
@@ -1012,6 +1589,11 @@ eurephiaVALUES *eDBload_sessiondata(eurephiaCTX *ctx, const char *sesskey)
int eDBstore_session_value(eurephiaCTX *ctx, eurephiaSESSION *session, int mode,
const char *key, const char *val)
{
+ const char **qry_args = NULL;
+ int prepid = -1, ret = 0;
+ _ePG_prepID preptype = PREPSQL_NONE;
+ PGresult *dbr = NULL;
+
if( session == NULL ) {
DEBUG(ctx, 20,
"Function call failed to eDBstore_session_value(ctx, ...): Non-existing session key");
@@ -1021,34 +1603,62 @@ int eDBstore_session_value(eurephiaCTX *ctx, eurephiaSESSION *session, int mode,
DEBUG(ctx, 20, "Function call: eDBstore_session_value(ctx, '%s', %i, '%s', '%s')",
session->sessionkey, mode, key, val);
+ /* TODO: Need testing */
+
switch( mode ) {
case SESSVAL_NEW:
- /*
- "INSERT INTO sessions (sessionkey, datakey, dataval) "
- "VALUES ('%q','%q','%q')", session->sessionkey, key, val);
- */
+ preptype = PREPSQL_SESSIONVARS_STORE_NEW;
+ prepid = ePGprepStatement(ctx, preptype,
+ "INSERT INTO sessions (sessionkey, datakey, dataval) "
+ "VALUES ($1::VARCHAR,$2::VARCHAR,$3::VARCHAR)", 3);
break;
case SESSVAL_UPDATE:
- /*
- "UPDATE sessions SET dataval = '%q' "
- " WHERE sessionkey = '%q' AND datakey = '%q'",
- val, session->sessionkey, key);
- */
+ preptype = PREPSQL_SESSIONVARS_STORE_UPDATE;
+ prepid = ePGprepStatement(ctx, preptype,
+ "UPDATE sessions SET dataval = $3::VARCHAR "
+ " WHERE sessionkey = $1::VARCHAR"
+ " AND datakey = $2::VARCHAR", 2);
+ break;
case SESSVAL_DELETE:
- /*
- "DELETE FROM sessions "
- " WHERE sessionkey = '%q' AND datakey = '%q'",
- session->sessionkey, key);
- */
+ preptype = PREPSQL_SESSIONVARS_STORE_DELETE;
+ prepid = ePGprepStatement(ctx, preptype,
+ "DELETE FROM sessions "
+ " WHERE sessionkey = $1::VARCHAR"
+ " AND datakey = $2::VARCHAR", 2);
break;
default:
eurephia_log(ctx, LOG_FATAL, 0, "Unknown eDBstore_session_value mode '%i'", mode);
return 0;
}
- return 1;
+
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, preptype,
+ "Failed to prepare SQL query");
+ return 0;
+ }
+
+ qry_args = calloc(3, sizeof(char *));
+ qry_args[0] = session->sessionkey;
+ qry_args[1] = key;
+ qry_args[2] = val;
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, preptype,
+ "eDBstore_session_value: Failed to update session value [%s] %s",
+ session->sessionkey, key);
+ ret = 0;
+ goto exit;
+ }
+ PQclear(dbr);
+ ret = 1;
+
+ exit:
+ free_nullsafe(ctx, qry_args);
+ return ret;
}
@@ -1057,6 +1667,10 @@ int eDBstore_session_value(eurephiaCTX *ctx, eurephiaSESSION *session, int mode,
*/
int eDBdestroy_session(eurephiaCTX *ctx, eurephiaSESSION *session)
{
+ const char **qry_args = NULL;
+ int prepid = -1, ret = 0;
+ PGresult *dbr = NULL;
+
DEBUG(ctx, 20, "Function call: eDBdestroy_session(ctx, '%s')", session->sessionkey);
if( (session == NULL) || (session->sessionkey == NULL) ) {
@@ -1064,25 +1678,73 @@ int eDBdestroy_session(eurephiaCTX *ctx, eurephiaSESSION *session)
return 1;
}
+ qry_args = calloc(1, sizeof(char *));
+ qry_args[0] = session->sessionkey;
+
// Update session status - if we have a "real" session (not auth-session)
if( session->type == stSESSION ) {
- /*
- "UPDATE lastlog "
- " SET sessionstatus = 4, session_deleted = CURRENT_TIMESTAMP "
- " WHERE sessionkey = '%q' AND sessionstatus = 3", session->sessionkey);
- */
- }
+ prepid = ePGprepStatement(ctx, PREPSQL_SESSIONS_DESTROY_LASTLOG,
+ "UPDATE lastlog_update "
+ " SET sessionstatus = 4,"
+ " session_deleted = CURRENT_TIMESTAMP "
+ " WHERE sessionkey = $1::VARCHAR"
+ " AND sessionstatus = 3", 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, dbr, LOG_FATAL, 0, PREPSQL_SESSIONS_DESTROY_LASTLOG,
+ "Failed to prepare SQL query");
+ ret = 0;
+ goto exit;
+ }
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0,
+ PREPSQL_SESSIONS_DESTROY_LASTLOG,
+ "eDBdestroy_session: Failed to update "
+ "update lastlog with session deleted status (%s)",
+ session->sessionkey);
+ ret = 0;
+ goto exit;
+ }
+ PQclear(dbr);
+ }
// Delete session variables
- /*
- "DELETE FROM sessions WHERE sessionkey = '%q'", session->sessionkey);
- */
-
- // Delete the session key
- /*
- "DELETE FROM sessionkeys WHERE sessionkey = '%q'", seskey);
- */
- return 0;
+ prepid = ePGprepStatement(ctx, PREPSQL_SESSIONS_DESTROY_SESS,
+ "DELETE FROM sessions WHERE sessionkey = $1::VARCHAR", 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0,
+ PREPSQL_SESSIONS_DESTROY_SESS,
+ "Failed to prepare SQL query");
+ ret = 0;
+ goto exit;
+ }
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_COMMAND_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0,
+ PREPSQL_SESSIONS_DESTROY_SESS,
+ "eDBdestroy_session: Failed to delete "
+ "session variables (%s)",
+ session->sessionkey);
+ ret = 0;
+ goto exit;
+ }
+ PQclear(dbr);
+
+ // Delete the session seed/session key relation
+ if( eDBremove_sessionkey(ctx, session->sessionkey) == 0) {
+ eurephia_log(ctx, LOG_CRITICAL, 0,
+ "Failed to delete sessionkey/sessionseed relation (%s)",
+ session->sessionkey);
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+
+ exit:
+ free_nullsafe(ctx, qry_args);
+ return ret;
}
@@ -1091,19 +1753,41 @@ int eDBdestroy_session(eurephiaCTX *ctx, eurephiaSESSION *session)
*/
char *eDBget_firewall_profile(eurephiaCTX *ctx, eurephiaSESSION *session)
{
+ const char **qry_args = NULL;
+ int prepid = -1;
char *ret = NULL;
-
+ PGresult *dbr = NULL;
DEBUG(ctx, 20, "Function call: eDBget_firewall_profile(ctx, {session}'%s')",
session->sessionkey);
- /*
- "SELECT fw_profile "
- " FROM lastlog "
- " JOIN usercerts USING(certid, uid)"
- " JOIN accesses USING(accessprofile)"
- " WHERE sessionkey = '%q'", session->sessionkey);
- */
+ /* TODO: Need testing */
+
+ prepid = ePGprepStatement(ctx, PREPSQL_FIREWALL_GETPROFILE,
+ "SELECT fw_profile "
+ " FROM lastlog "
+ " JOIN usercerts USING(certid, uid)"
+ " JOIN accesses USING(accessprofile)"
+ " WHERE sessionkey = $1::VARCHAR", 1);
+ if( prepid < 0 ) {
+ ePGerrorMessage(ctx, NULL, LOG_FATAL, 0, PREPSQL_FIREWALL_GETPROFILE,
+ "Failed to prepare SQL query");
+ return NULL;
+ }
+
+ qry_args = calloc(1, sizeof(char *));
+ qry_args[0] = session->sessionkey;
+
+ dbr = ePGprepExec(ctx, prepid, qry_args);
+ free_nullsafe(ctx,qry_args);
+ if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) || (PQntuples(dbr) > 1) ) {
+ ePGerrorMessage(ctx, dbr, LOG_WARNING, 0, PREPSQL_FIREWALL_GETPROFILE,
+ "Failed to retrieve the firewall profile for session '%s'",
+ session->sessionkey);
+ return NULL;
+ }
+ ret = (PQntuples(dbr) == 1 ? strdup_nullsafe(ePGgetValue(dbr, 0, 0)) : NULL);
+ PQclear(dbr);
return ret;
}
@@ -1114,17 +1798,33 @@ char *eDBget_firewall_profile(eurephiaCTX *ctx, eurephiaSESSION *session)
*/
eurephiaVALUES *eDBget_blacklisted_ip(eurephiaCTX *ctx)
{
+ int i = 0;
+ PGresult *dbr = NULL;
eurephiaVALUES *ret = NULL;
DEBUG(ctx, 20, "Function call: eDBget_blacklisted_ip(ctx)");
- /*
- "SELECT remoteip FROM blacklist WHERE remoteip IS NOT NULL");
- */
+ if( !ctx || !ctx->dbc || !ctx->dbc->dbhandle ) {
+ eurephia_log(ctx, LOG_FATAL, 0, "System error in eDBget_blacklisted_ip()");
+ return NULL;
+ }
+
+ dbr = PQexec(ctx->dbc->dbhandle, "SELECT remoteip FROM blacklist WHERE remoteip IS NOT NULL");
+ if( !dbr || (PQresultStatus(dbr) != PGRES_TUPLES_OK) ) {
+ ePGerrorMessage(ctx, dbr, LOG_CRITICAL, 0, PREPSQL_NONE,
+ "eDBget_blaclisted_ip: Failed to query IP blacklist");
+ return NULL;
+ }
+ // Copy blacklisted IP addresses into a eurephiaVALUES chain without key names
ret = eCreate_value_space(ctx, 21);
- // copy SQL result into eurephiaVALUES chain
+ for( i = 0; i < PQntuples(dbr); i++ ) {
+ char *ip = ePGgetValue(dbr, i, 0);
+ if( (ip != NULL) && (*ip != '\0') ) {
+ eAdd_value(ctx, ret, NULL, ip);
+ }
+ }
+ PQclear(dbr);
return ret;
-
}