edb-sqlite.c

Go to the documentation of this file.
00001 /*  edb-sqlite.c  --  Main driver for eurephia authentication plugin for OpenVPN
00002  *                    This is the SQLite database driver
00003  *
00004  *  GPLv2 only - Copyright (C) 2008 - 2010
00005  *               David Sommerseth <dazo@users.sourceforge.net>
00006  *
00007  *  This program is free software; you can redistribute it and/or
00008  *  modify it under the terms of the GNU General Public License
00009  *  as published by the Free Software Foundation; version 2
00010  *  of the License.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  *
00021  */
00022 
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <unistd.h>
00038 #include <assert.h>
00039 
00040 #define DRIVERVERSION "1.1"     
00041 #ifndef DRIVERAPIVERSION
00042 # define DRIVERAPIVERSION 2     
00043 #endif
00044 
00045 #include <sqlite3.h>
00046 
00047 #include <eurephiadb_driver.h>
00048 #include <eurephia_nullsafe.h>
00049 #include <eurephia_log.h>
00050 #include <eurephia_values.h>
00051 #include <eurephiadb_session_common.h>
00052 #include <eurephiadb_session_struct.h>
00053 #include <passwd.h>
00054 
00055 #include "sqlite.h"
00056 
00057 
00058 
00063 typedef struct {
00064         char *colname;          
00065         char *colname_where;    
00066         char *allow_cfg;        
00067         char *descr;            
00068         char *default_value;    
00069         char *value_func;       
00070 } eDBattempt_types_t;
00071                
00072 
00076 static const eDBattempt_types_t eDBattempt_types[] = {
00077         {NULL, NULL, NULL, NULL},
00078         {"remoteip\0", "remoteip\0", "allow_ipaddr_attempts\0", "IP Address\0", "10\0", NULL},
00079         {"digest\0", "lower(digest)\0", "allow_cert_attempts\0", "Certificate\0", "5\0", "lower\0"},
00080         {"username\0", "username\0", "allow_username_attempts\0", "Username\0", "5\0", NULL},
00081         {NULL, NULL, NULL, NULL}
00082 };
00083 
00084 
00088 const char *eDB_DriverVersion(void) {
00089         return "eurephiadb-sqlite (v"DRIVERVERSION")  David Sommerseth 2008 (C) GPLv2";
00090 }
00091 
00092 
00096 int eDB_DriverAPIVersion() {
00097         return DRIVERAPIVERSION;
00098 }
00099 
00100 
00101 /*
00102  *   local functions
00103  */
00104 
00105 
00113 void update_attempts(eurephiaCTX *ctx, const char *blid) {
00114         dbresult *res = NULL;
00115 
00116         if( blid != NULL ) {
00117                 res = sqlite_query(ctx, 
00118                                    "UPDATE openvpn_blacklist "
00119                                    "   SET last_accessed = CURRENT_TIMESTAMP WHERE blid = %q", blid);
00120                 if( res == NULL ) {
00121                         eurephia_log(ctx, LOG_CRITICAL, 0,
00122                                      "Could not update openvpn_blacklist.last_accessed for blid=%s", blid);
00123                 }
00124                 sqlite_free_results(res);
00125         }
00126 }
00127 
00128 /*
00129  *   Public driver functions
00130  */
00131 
00136 int eDBconnect(eurephiaCTX *ctx, const int argc, const char **argv)
00137 {
00138         eDBconn *dbc = NULL;
00139         dbresult *res = NULL;
00140         int rc;
00141 
00142         DEBUG(ctx, 20, "Function call: eDBconnect(ctx, %i, '%s')", argc, argv[0]);
00143 
00144         if( (argc != 1) || (argv[0] == NULL) || (strlen(argv[0]) < 1) ) {
00145                 eurephia_log(ctx, LOG_PANIC, 0, "Wrong parameters to eurephiadb-sqlite.  Cannot open database.");
00146                 return 0;
00147         }
00148         
00149         // Connect to the database
00150         dbc = (eDBconn *) malloc_nullsafe(ctx, sizeof(eDBconn)+2);
00151         dbc->dbname = strdup(argv[0]);
00152 
00153         eurephia_log(ctx, LOG_INFO, 1, "Opening database '%s'", dbc->dbname);
00154 
00155         rc = sqlite3_open(argv[0], (void *) &dbc->dbhandle);
00156         if( rc ) {
00157                 eurephia_log(ctx, LOG_PANIC, 0, "Could not open database '%s'", dbc->dbname);
00158                 free_nullsafe(ctx, dbc->dbname);
00159                 free_nullsafe(ctx, dbc);
00160                 return 0;
00161         }
00162 
00163         dbc->config = NULL;
00164         ctx->dbc = dbc;
00165 
00166         // Load configuration parameters into memory
00167         eurephia_log(ctx, LOG_INFO, 1, "Reading config from database (openvpn_config)");
00168         res = sqlite_query(ctx, "SELECT datakey, dataval FROM openvpn_config");
00169         if( res != NULL ) {
00170                 int i = 0;
00171                 eurephiaVALUES *cfg = NULL;
00172                 
00173                 cfg = eCreate_value_space(ctx, 11);
00174                 if( cfg == NULL ) {
00175                         eurephia_log(ctx, LOG_FATAL, 0, "Could not allocate memory for config variables");
00176                         sqlite_free_results(res);
00177                         return 0;
00178                 }
00179                 for( i = 0; i < sqlite_get_numtuples(res); i++ ) {
00180                         eAdd_value(ctx, cfg, sqlite_get_value(res, i, 0), sqlite_get_value(res, i, 1));
00181                 }
00182                 sqlite_free_results(res);
00183                 ctx->dbc->config = cfg;
00184         } 
00185         return 1;
00186 }
00187 
00192 void eDBdisconnect(eurephiaCTX *ctx) 
00193 {
00194         eDBconn *dbc = NULL;
00195 
00196         DEBUG(ctx, 20, "Function call: eDBdisconnect(ctx)");
00197 
00198         if( ctx->dbc == NULL ) {
00199                 eurephia_log(ctx, LOG_WARNING, 0, "Database not open, cannot close database.");
00200                 return;
00201         }
00202 
00203         dbc = ctx->dbc;
00204         eurephia_log(ctx, LOG_INFO, 1, "Closing database '%s'", dbc->dbname);
00205 
00206         // Close database connection
00207         sqlite3_close((sqlite3 *) dbc->dbhandle);
00208         free_nullsafe(ctx, dbc->dbname);
00209         dbc->dbhandle = NULL;
00210 
00211         // Free up config memory
00212         eFree_values(ctx, dbc->config);
00213         free_nullsafe(ctx, dbc);
00214         ctx->dbc = NULL;
00215 }
00216 
00217 
00221 int eDBauth_TLS(eurephiaCTX *ctx, const char *org, const char *cname, const char *email, 
00222                 const char *digest, const unsigned int depth)
00223 {
00224         dbresult *res = NULL;
00225         int certid = 0;
00226         char *blid = NULL;
00227 
00228         DEBUG(ctx, 20, "Function call: eDBauth_TLS(ctx, '%s', '%s', '%s', '%s', %i)",
00229               org, cname, email, digest, depth);
00230 
00231         // Check if certificate is valid, and not too many attempts has been tried with the given certificate
00232         res = sqlite_query(ctx, 
00233                            "SELECT cert.certid, blid "
00234                            "  FROM openvpn_certificates cert"
00235                            "  LEFT JOIN openvpn_blacklist bl USING(digest)"
00236                            " WHERE organisation='%q' AND common_name='%q' "
00237                            "      AND email='%q' AND depth='%i' AND lower(cert.digest)=lower('%q')%c",
00238                            org, cname, email, depth, digest, 0);
00239 
00240         if( res != NULL ) {
00241                 certid = atoi_nullsafe(sqlite_get_value(res, 0, 0));
00242                 blid = strdup_nullsafe(sqlite_get_value(res, 0, 1));
00243                 sqlite_free_results(res);
00244 
00245                 // Check if the certificate is blacklisted or not.  blid != NULL when blacklisted
00246                 if( blid != NULL ) {
00247                         // If the certificate or IP is blacklisted, update status and deny access.
00248                         eurephia_log(ctx, LOG_WARNING, 0,
00249                                      "Attempt with BLACKLISTED certificate (certid %i)", certid);
00250                         update_attempts(ctx, blid);
00251                         certid = -1;
00252                 }
00253                 free_nullsafe(ctx, blid);
00254         } else {
00255                 eurephia_log(ctx, LOG_FATAL, 0, "Could not look up certificate information");
00256         }
00257 
00258         DEBUG(ctx, 20, "Result function call: eDBauth_TLS(ctx, '%s', '%s', '%s', '%s', %i) - %i",
00259               org, cname, email, digest, depth, certid);
00260 
00261         return certid;
00262 }
00263 
00264 
00268 int eDBauth_user(eurephiaCTX *ctx, const int certid, const char *username, const char *passwd) 
00269 {
00270         dbresult *res = NULL;
00271         char *crpwd = NULL, *activated = NULL, *deactivated = NULL, *blid_uname = NULL, *blid_cert = NULL;
00272         char *dbpwd = NULL;
00273         int uicid = 0, uid = 0, pwdok = 0;
00274 
00275         DEBUG(ctx, 20, "Function call: eDBauth_user(ctx, %i, '%s','xxxxxxxx')", certid, username);
00276 
00277 
00278         // Generate SHA512 hash of password, used for password auth
00279         res = sqlite_query(ctx,
00280                            "SELECT uicid, ou.uid, activated, deactivated, bl1.blid, bl2.blid, password "
00281                            "  FROM openvpn_users ou"
00282                            "  JOIN openvpn_usercerts uc USING(uid) "
00283                            "  LEFT JOIN openvpn_blacklist bl1 ON( ou.username = bl1.username) "
00284                            "  LEFT JOIN (SELECT blid, certid "
00285                            "               FROM openvpn_certificates "
00286                            "               JOIN openvpn_blacklist USING(digest)) bl2 ON(uc.certid = bl2.certid)"
00287                            " WHERE uc.certid = '%i' AND ou.username = '%q'",
00288                            certid, username);
00289         memset(crpwd, 0, strlen_nullsafe(crpwd));
00290         free_nullsafe(ctx, crpwd);
00291         if( res == NULL ) {
00292                 eurephia_log(ctx, LOG_FATAL, 0,
00293                              "Could not lookup user in database (certid %i, username '%s'", certid, username);
00294                 return 0;
00295         }
00296 
00297         if( sqlite_get_numtuples(res) == 1 ) {
00298                 uid         = atoi_nullsafe(sqlite_get_value(res, 0, 1));
00299                 activated   = sqlite_get_value(res, 0, 2);
00300                 deactivated = sqlite_get_value(res, 0, 3);
00301                 blid_uname  = sqlite_get_value(res, 0, 4);
00302                 blid_cert   = sqlite_get_value(res, 0, 5);
00303                 dbpwd       = sqlite_get_value(res, 0, 6);
00304 
00305                 if( dbpwd == NULL ) {
00306                         eurephia_log(ctx, LOG_WARNING, 0,"Authentication failed for user '%s'. DB error.",
00307                                      username);
00308                         pwdok = 0;
00309                 } else {
00310                         crpwd = eurephia_pwd_crypt(ctx, passwd, dbpwd);
00311                         pwdok = ((crpwd != NULL) && (strcmp(crpwd, dbpwd) == 0) ? 1 : 0);
00312                         memset(crpwd, 0, strlen_nullsafe(crpwd));
00313                         memset(dbpwd, 0, strlen_nullsafe(dbpwd));
00314                         free_nullsafe(ctx, crpwd);
00315                 }
00316 
00317                 if( blid_uname != NULL ) {
00318                         eurephia_log(ctx, LOG_WARNING, 0, "User account is BLACKLISTED (uid: %i, %s)",
00319                                      uid, username);
00320                         uicid = -1;
00321                 } else if( blid_cert != NULL ) {
00322                         eurephia_log(ctx, LOG_WARNING, 0,
00323                                      "User account linked with a BLACKLISTED certificate "
00324                                      "(uid: %i, %s) - certid: %s",
00325                                      uid, username, certid);
00326                         uicid = -1;
00327                 } else if( activated == NULL ) {
00328                         eurephia_log(ctx, LOG_WARNING, 0, "User account is not activated (uid: %i, %s)",
00329                                      uid, username);
00330                         uicid = -1;
00331                 } else if( deactivated != NULL ) {
00332                         eurephia_log(ctx, LOG_WARNING, 0, "User account is deactivated (uid: %i, %s)",
00333                                      uid, username);
00334                         uicid = -1;
00335                 } else if( pwdok != 1 ) {
00336                         eurephia_log(ctx, LOG_WARNING, 0,"Authentication failed for user '%s'. Wrong password.",
00337                                      username);
00338                         sleep(2);
00339                         uicid = -1;
00340                 } else {
00341                         dbresult *upd = NULL;
00342 
00343                         uicid = atoi_nullsafe(sqlite_get_value(res, 0, 0));
00344 
00345                         // Update last accessed status
00346                         upd = sqlite_query(ctx,
00347                                            "UPDATE openvpn_users SET last_accessed = CURRENT_TIMESTAMP"
00348                                            " WHERE uid = %i", uid);
00349                         if( upd == NULL ) {
00350                                 eurephia_log(ctx, LOG_ERROR, 0,
00351                                              "Could not update last access status for uid %i", uid);
00352                         } else {
00353                                 sqlite_free_results(upd);
00354                         }
00355                 }
00356         } else {
00357                 eurephia_log(ctx, LOG_WARNING, 0, "Authentication failed for user '%s'.  "
00358                              "Could not find user or user-certificate link.", username);
00359                 sleep(2);
00360                 uicid = 0;
00361         }
00362         sqlite_free_results(res);
00363 
00364         DEBUG(ctx, 20, "Result function call: eDBauth_user(ctx, %i, '%s','xxxxxxxx') - %i",
00365               certid, username, uicid);
00366 
00367         return uicid;
00368 }
00369 
00373 int eDBget_uid(eurephiaCTX *ctx, const int certid, const char *username)  
00374 {
00375         dbresult *res = NULL;
00376         int ret = 0;
00377 
00378         DEBUG(ctx, 20, "Function call: eDBget_uid(ctx, %i, '%s')", certid, username);
00379 
00380         res = sqlite_query(ctx,
00381                            "SELECT uid "
00382                            "  FROM openvpn_usercerts "
00383                            "  JOIN openvpn_users USING (uid) "
00384                            " WHERE certid = '%i' AND username = '%q'",
00385                            certid, username);
00386         if( (res == NULL) || (sqlite_get_numtuples(res) != 1) ) {
00387                 eurephia_log(ctx, LOG_FATAL, 0, "Could not lookup userid for user '%s'", username);
00388                 ret = -1;
00389         } else {
00390                 ret = atoi_nullsafe(sqlite_get_value(res, 0, 0));
00391         }
00392         sqlite_free_results(res);
00393 
00394         return ret;
00395 }
00396 
00397 
00401 int eDBblacklist_check(eurephiaCTX *ctx, const int type, const char *val)
00402 {
00403         dbresult *blr = NULL, *atpr = NULL;
00404         int atpexceed = -1, blacklisted = 0;
00405         char *atpid = NULL, *blid = NULL;
00406 
00407         DEBUG(ctx, 20, "Function call: eDBblacklist_check(ctx, '%s', '%s')",
00408               eDBattempt_types[type].descr, val);
00409 
00410         blr  = sqlite_query(ctx, "SELECT blid FROM openvpn_blacklist WHERE %s = %s%s'%q'%s",
00411                             eDBattempt_types[type].colname_where,
00412                             defaultValue(eDBattempt_types[type].value_func, ""),
00413                             (strlen_nullsafe(eDBattempt_types[type].value_func) > 0 ? "(" : ""),
00414                             val,
00415                             (strlen_nullsafe(eDBattempt_types[type].value_func) > 0 ? ")" : ""));
00416         if( blr != NULL ) {
00417                 blid = strdup_nullsafe(sqlite_get_value(blr, 0, 0));
00418                 sqlite_free_results(blr);
00419                 blr = NULL;
00420 
00421                 if( blid != NULL ) {
00422                         eurephia_log(ctx, LOG_WARNING, 0, "Attempt from blacklisted %s: %s",
00423                                      eDBattempt_types[type].descr, val);
00424                         blacklisted = 1; // [type] is blacklisted
00425                 }
00426                 // Update attempt information
00427                 update_attempts(ctx, blid);
00428         } else {
00429                 eurephia_log(ctx, LOG_FATAL, 0, "Quering openvpn_blacklist for blacklisted %s failed",
00430                              eDBattempt_types[type].descr);
00431         }
00432 
00433         if( blacklisted == 0 ) {
00434                 // Check if this [type] has been attempted earlier - if it has reaced the maximum 
00435                 // attempt limit, blacklist it
00436                 atpr = sqlite_query(ctx,
00437                                     "SELECT atpid, attempts >= %q FROM openvpn_attempts WHERE %s = '%q'",
00438                                     defaultValue(eGet_value(ctx->dbc->config, eDBattempt_types[type].allow_cfg),
00439                                                   eDBattempt_types[type].default_value),
00440                                     eDBattempt_types[type].colname_where, val);
00441                 if( atpr != NULL ) {
00442                         atpid = strdup_nullsafe(sqlite_get_value(atpr, 0, 0));
00443                         atpexceed = atoi_nullsafe(sqlite_get_value(atpr, 0, 1));
00444                         sqlite_free_results(atpr);
00445                         atpr = NULL;
00446                         
00447                         // If [type] has reached attempt limit and it is not black listed, black list it
00448                         if( (atpexceed > 0) && (blid == NULL) ) {
00449                                 eurephia_log(ctx, LOG_WARNING, 0,
00450                                              "%s got BLACKLISTED due to too many failed attempts: %s",
00451                                              eDBattempt_types[type].descr, val);
00452                                 blr = sqlite_query(ctx, 
00453                                                    "INSERT INTO openvpn_blacklist (%s) VALUES ('%q')",
00454                                                    eDBattempt_types[type].colname, val);
00455                                 if( blr == NULL ) {
00456                                         eurephia_log(ctx, LOG_CRITICAL, 0,
00457                                                      "Could not blacklist %s (%s)",
00458                                                      eDBattempt_types[type].descr, val);
00459                                 }
00460                                 sqlite_free_results(blr);
00461                                 blacklisted = 1; // [type] is blacklisted
00462                         }
00463                         free_nullsafe(ctx, atpid);
00464                 } else {
00465                         eurephia_log(ctx, LOG_CRITICAL, 0, "Quering openvpn_attempts for blacklisted %s failed",
00466                                      eDBattempt_types[type].descr);
00467                 }
00468                 free_nullsafe(ctx, atpr);
00469         }
00470         free_nullsafe(ctx, blid);
00471 
00472         DEBUG(ctx, 20, "Result - function call: eDBblacklist_check(ctx, '%s', '%s') - %i",
00473               eDBattempt_types[type].descr, val, blacklisted);
00474 
00475         return blacklisted;
00476 }
00477 
00481 void eDBregister_attempt(eurephiaCTX *ctx, int type, int mode, const char *value) {
00482         dbresult *res;
00483         char *id = NULL, *atmpt_block = NULL, *blid = NULL;
00484         int attempts = 0;
00485 
00486         DEBUG(ctx, 20, "Function call: eDBregister_attempt(ctx, %s, %s, '%s')",
00487               eDBattempt_types[type].colname,
00488               (mode == ATTEMPT_RESET ? "ATTEMPT_RESET" : "ATTEMPT_REGISTER"),
00489               value);
00490 
00491         //
00492         //  openvpn_attempts
00493         //
00494         res = sqlite_query(ctx, 
00495                            "SELECT atpid, attempts > %s, blid, attempts "
00496                            "  FROM openvpn_attempts "
00497                            "  LEFT JOIN openvpn_blacklist USING(%s)"
00498                            " WHERE %s = %s%s'%q'%s",
00499                            defaultValue(eGet_value(ctx->dbc->config, eDBattempt_types[type].allow_cfg),
00500                                         eDBattempt_types[type].default_value),
00501                            eDBattempt_types[type].colname,
00502                            eDBattempt_types[type].colname_where,
00503                            defaultValue(eDBattempt_types[type].value_func, ""),
00504                            (strlen_nullsafe(eDBattempt_types[type].value_func) > 0 ? "(" : ""),
00505                            value,
00506                            (strlen_nullsafe(eDBattempt_types[type].value_func) > 0 ? ")" : "")
00507                            );
00508         if( res == NULL ) {
00509                 eurephia_log(ctx, LOG_FATAL, 0, "Could not look up atpid in openvpn_attempts");
00510                 return;
00511         }
00512 
00513         attempts = atoi_nullsafe(sqlite_get_value(res, 0, 3));
00514         // If we are asked to reset the attempt counter and we do not find any attempts, exit here
00515         if( (mode == ATTEMPT_RESET) && ((sqlite_get_numtuples(res) == 0) || (attempts == 0))) {
00516                 sqlite_free_results(res);
00517                 return;
00518         }
00519 
00520         id = strdup_nullsafe(sqlite_get_value(res, 0, 0));
00521         atmpt_block = strdup_nullsafe(sqlite_get_value(res, 0, 1));
00522         blid = strdup_nullsafe(sqlite_get_value(res, 0, 2));
00523 
00524         sqlite_free_results(res);
00525 
00526         if( (id == NULL) && (mode == ATTEMPT_REGISTER) ) {
00527                 // Only insert record when we are in registering mode
00528                 res = sqlite_query(ctx, "INSERT INTO openvpn_attempts (%s, attempts) VALUES ('%q', 1)",
00529                                    eDBattempt_types[type].colname, value);
00530         } else if( id != NULL ){
00531                 // if a attempt record exists, update it according to mode
00532                 switch( mode ) {
00533                 case ATTEMPT_RESET:
00534                         res = sqlite_query(ctx,
00535                                            "UPDATE openvpn_attempts "
00536                                            "   SET attempts = 0 "
00537                                            " WHERE atpid = '%q'", id);
00538                         break;
00539                 default:
00540                         res = sqlite_query(ctx,
00541                                            "UPDATE openvpn_attempts "
00542                                            "   SET last_attempt = CURRENT_TIMESTAMP, attempts = attempts + 1"
00543                                            " WHERE atpid = '%q'", id);
00544                         break;
00545                 }
00546         }
00547         if( res == NULL ) {
00548                 eurephia_log(ctx, LOG_CRITICAL, 0, 
00549                              "Could not update openvpn_attempts for %s = %s", 
00550                              eDBattempt_types[type].colname, value);
00551         }
00552         sqlite_free_results(res);
00553 
00554         //  If attempts have exceeded attempt limit, blacklist it immediately if not already registered
00555         if( (mode == ATTEMPT_REGISTER) 
00556             && (blid == NULL) && (atmpt_block != NULL) && (atoi_nullsafe(atmpt_block) > 0) ) {
00557                 eurephia_log(ctx, LOG_WARNING, 0, "Blacklisting %s due to too many attempts: %s",
00558                              eDBattempt_types[type].descr, value);
00559                 res = sqlite_query(ctx, "INSERT INTO openvpn_blacklist (%s) VALUES ('%q')",
00560                                    eDBattempt_types[type].colname, value);
00561                 if( res == NULL ) {
00562                         eurephia_log(ctx, LOG_CRITICAL, 0, 
00563                                      "Could not blacklist %s: %s", eDBattempt_types[type].descr, value);
00564                 }
00565                 sqlite_free_results(res);
00566         }
00567         free_nullsafe(ctx, id);
00568         free_nullsafe(ctx, atmpt_block);
00569         free_nullsafe(ctx, blid);
00570 }
00571 
00572 
00576 int eDBregister_login(eurephiaCTX *ctx, eurephiaSESSION *skey, const int certid, const int uid, 
00577                       const char *proto, const char *remipaddr, const char *remport, 
00578                       const char *vpnipaddr, const char *vpnipmask) 
00579 {
00580         dbresult *res = NULL;
00581 
00582         DEBUG(ctx, 20, "Function call: eDBregister_login(ctx, '%s', %i, %i, '%s','%s','%s','%s','%s')",
00583               skey->sessionkey, certid, uid, proto, remipaddr, remport, vpnipaddr, vpnipmask);
00584         
00585         if( skey->sessionstatus != SESSION_NEW ) {
00586                 eurephia_log(ctx, LOG_ERROR, 5, "Not a new session, will not register it again");
00587                 return 1;
00588         }
00589 
00590         res = sqlite_query(ctx, 
00591                            "INSERT INTO openvpn_lastlog (uid, certid, "
00592                            "                             protocol, remotehost, remoteport,"
00593                            "                             vpnipaddr, vpnipmask,"
00594                            "                             sessionstatus, sessionkey, login) "
00595                            "VALUES (%i, %i, '%q','%q','%q','%q','%q', 1,'%q', CURRENT_TIMESTAMP)",
00596                            uid, certid, proto, remipaddr, remport, vpnipaddr, vpnipmask, skey->sessionkey);
00597         if( res == NULL ) {
00598                 eurephia_log(ctx, LOG_FATAL, 0, "Could not insert new session into openvpn_lastlog");
00599                 return 0;
00600         }
00601         sqlite_free_results(res);
00602         skey->sessionstatus = SESSION_REGISTERED;
00603         return 1;
00604 }
00605 
00609 int eDBregister_vpnmacaddr(eurephiaCTX *ctx, eurephiaSESSION *session, const char *macaddr)
00610 {
00611         dbresult *res = NULL;
00612 
00613         DEBUG(ctx, 20, "Function call: eDBregister_vpnmacaddr(ctx, '%s', '%s')",
00614               session->sessionkey, macaddr);
00615 
00616         if( (macaddr == NULL) && (strlen_nullsafe(macaddr) > 18) ) {
00617                 eurephia_log(ctx, LOG_FATAL, 0, "Invalid MAC address");
00618                 return 0;
00619         }
00620 
00621         // Register MAC address into history table
00622         res = sqlite_query(ctx, "INSERT INTO openvpn_macaddr_history (sessionkey, macaddr) VALUES ('%q','%q')",
00623                            session->sessionkey, macaddr);
00624         if( res == NULL ) {
00625                 eurephia_log(ctx, LOG_FATAL, 0, "Failed to log new MAC address for session");
00626                 return 0;
00627         }
00628         sqlite_free_results(res);
00629 
00630         // Update lastlog to reflect last used MAC address for the session
00631         res = sqlite_query(ctx, 
00632                            "UPDATE openvpn_lastlog SET sessionstatus = 2, macaddr = '%q' "
00633                            " WHERE sessionkey = '%q' AND sessionstatus = 1", macaddr, session->sessionkey);
00634         if( res == NULL ) {
00635                 eurephia_log(ctx, LOG_FATAL, 0, "Could not update lastlog with new MAC address for session");
00636                 return 0;
00637                 
00638         }
00639         sqlite_free_results(res);
00640 
00641         // Save the MAC address in the session values register - needed for the destroy session
00642         if( eDBset_session_value(ctx, session, "macaddr", macaddr) == 0 ) {
00643                 eurephia_log(ctx, LOG_FATAL, 0, "Could not save MAC address into session variables");
00644                 return 0;
00645         }
00646 
00647         return 1;
00648 }
00649 
00650 
00654 int eDBregister_logout(eurephiaCTX *ctx, eurephiaSESSION *skey, 
00655                        const char *bytes_sent, const char *bytes_received, const char *duration)
00656 {
00657         dbresult *res = NULL;
00658 
00659         DEBUG(ctx, 20, "Function call: eDBregister_logout(ctx, '%s', %s, %s)",
00660               skey->sessionkey, bytes_sent, bytes_received);
00661 
00662         res = sqlite_query(ctx, 
00663                            "UPDATE openvpn_lastlog "
00664                            "   SET sessionstatus = 3, logout = CURRENT_TIMESTAMP, "
00665                            "       bytes_sent = '%i', bytes_received = '%i', session_duration = '%i' "
00666                            " WHERE sessionkey = '%q' AND sessionstatus = 2",
00667                            atoi_nullsafe(bytes_sent), atoi_nullsafe(bytes_received),
00668                            atoi_nullsafe(duration), skey->sessionkey);
00669         if( res == NULL ) {
00670                 eurephia_log(ctx, LOG_FATAL, 0, "Could not update lastlog with logout information (%s)",
00671                              skey->sessionkey);
00672                 return 0;
00673         }
00674         sqlite_free_results(res);
00675         skey->sessionstatus = SESSION_LOGGEDOUT;
00676         return 1;
00677 }
00678 
00679 
00683 char *eDBget_sessionkey_seed(eurephiaCTX *ctx, sessionType type, const char *sessionseed) {
00684         dbresult *res = NULL;
00685         char *skey = NULL;
00686 
00687         DEBUG(ctx, 20, "eDBget_sessionkey_seed(ctx, %i, '%s')", type, sessionseed);
00688 
00689         if( sessionseed == NULL ) {
00690                 eurephia_log(ctx, LOG_FATAL, 1,
00691                              "eDBget_sessionkey: No session seed given - cannot locate sessionkey");
00692                 return NULL;
00693         }
00694 
00695         switch( type ) {
00696         case stSESSION:
00697                 res = sqlite_query(ctx,
00698                                    "SELECT sessionkey "
00699                                    "  FROM openvpn_sessionkeys "
00700                                    "  JOIN openvpn_lastlog USING (sessionkey)"
00701                                    " WHERE sessionstatus IN (1,2)"
00702                                    "       AND sessionseed = '%q'",
00703                                    sessionseed);
00704                 break;
00705 
00706         case stAUTHENTICATION:
00707                 res = sqlite_query(ctx,
00708                                    "SELECT sessionkey"
00709                                    "  FROM openvpn_sessionkeys"
00710                                    "  LEFT JOIN openvpn_lastlog USING(sessionkey)"
00711                                    " WHERE sessionstatus IS NULL"
00712                                    "   AND sessionseed = '%q'",
00713                                    sessionseed);
00714                 break;
00715 
00716         default:
00717                 eurephia_log(ctx, LOG_ERROR, 0, "Invalid session type: %i", type);
00718                 return NULL;
00719         }
00720 
00721         if( res == NULL ) {
00722                 eurephia_log(ctx, LOG_FATAL, 0,"Could not retrieve sessionkey from openvpn_sessionkeys (%s)",
00723                              sessionseed);
00724                 return NULL;
00725         } 
00726         if( sqlite_get_numtuples(res) == 1 ) {
00727                 skey = strdup_nullsafe(sqlite_get_value(res, 0, 0));
00728         } else {
00729                 skey = NULL;
00730         }
00731         sqlite_free_results(res);
00732         return skey;
00733 }
00734 
00735 
00739 char *eDBget_sessionkey_macaddr(eurephiaCTX *ctx, const char *macaddr) {
00740         dbresult *res = NULL;
00741         char *skey = NULL;
00742 
00743         DEBUG(ctx, 20, "eDBget_sessionkey_macaddr(ctx, '%s')", macaddr);
00744 
00745         // Find sessionkey from MAC address
00746         res = sqlite_query(ctx,
00747                            "SELECT sessionkey "
00748                            "  FROM openvpn_sessions "
00749                            "  JOIN openvpn_lastlog USING (sessionkey)"
00750                            " WHERE sessionstatus = 3 "
00751                            "       AND datakey = 'macaddr'"
00752                            "       AND dataval = '%q'", macaddr);
00753         if( res == NULL ) {
00754                 eurephia_log(ctx, LOG_FATAL, 0,
00755                              "Could not remove session from database (MAC addr: %s)", macaddr);
00756                 return 0;
00757         }
00758         skey = strdup_nullsafe(sqlite_get_value(res, 0, 0));
00759         sqlite_free_results(res);
00760 
00761         return skey;
00762 }
00763 
00764 
00768 int eDBcheck_sessionkey_uniqueness(eurephiaCTX *ctx, const char *seskey) {
00769         dbresult *res;
00770         int uniq = 0;
00771 
00772         DEBUG(ctx, 20, "eDBcheck_sessionkey_uniqueness(ctx, '%s')", seskey);
00773         if( seskey == NULL ) {
00774                 eurephia_log(ctx, LOG_FATAL, 1,
00775                              "eDBcheck_sessionkey_uniqness: Invalid session key given");
00776                 return 0;
00777         }
00778 
00779         switch( ctx->context_type ) {
00780         case ECTX_NO_PRIVILEGES:
00781                 return 0;
00782                 break;
00783 
00784         case ECTX_ADMIN_CONSOLE:
00785         case ECTX_ADMIN_WEB:
00786                 res = sqlite_query(ctx,
00787                                    "SELECT count(sessionkey) = 0 "
00788                                    "FROM eurephia_adminlog WHERE sessionkey = '%q'", seskey);
00789                 break;
00790 
00791         case ECTX_PLUGIN_AUTH:
00792         default:
00793                 res = sqlite_query(ctx,
00794                                    "SELECT count(sessionkey) = 0 "
00795                                    "FROM openvpn_lastlog WHERE sessionkey = '%q'", seskey);
00796                 break;
00797         }
00798 
00799         if( res == NULL ) {
00800                 eurephia_log(ctx, LOG_FATAL, 0,
00801                              "eDBcheck_sessionkey_uniqness: Could not check uniqueness of sessionkey");
00802                 return 0;
00803         }
00804         uniq = atoi_nullsafe(sqlite_get_value(res, 0, 0));
00805         sqlite_free_results(res);
00806 
00807         return uniq;
00808 }
00809 
00810 
00814 int eDBregister_sessionkey(eurephiaCTX *ctx, const char *seed, const char *seskey) {
00815         dbresult *res;
00816 
00817         DEBUG(ctx, 20, "eDBregister_sessionkey(ctx, '%s', '%s')", seed, seskey);
00818         if( (seed == NULL) || (seskey == NULL) ) {
00819                 eurephia_log(ctx, LOG_FATAL, 1,
00820                              "eDBregister_sessionkey: Invalid session seed or session key given");
00821                 return 0;
00822         }
00823 
00824         res = sqlite_query(ctx,
00825                            "INSERT INTO openvpn_sessionkeys (sessionseed, sessionkey) VALUES('%q','%q')",
00826                            seed, seskey);
00827         if( res == NULL ) {
00828                 eurephia_log(ctx, LOG_FATAL, 0,
00829                              "eDBregister_sessionkey: Error registering sessionkey into openvpn_sessionkeys");
00830                 return 0;
00831         }
00832         sqlite_free_results(res);
00833         return 1;
00834 }
00835 
00845 int eDBremove_sessionkey(eurephiaCTX *ctx, const char *seskey) {
00846         dbresult *res;
00847 
00848         DEBUG(ctx, 20, "eDBremove_sessionkey(ctx, '%s')", seskey);
00849         if( seskey == NULL ) {
00850                 eurephia_log(ctx, LOG_FATAL, 1,
00851                              "eDBremove_sessionkey: Invalid session key given");
00852                 return 0;
00853         }
00854 
00855         res = sqlite_query(ctx, "DELETE FROM openvpn_sessionkeys WHERE sessionkey = '%q'", seskey);
00856         if( res == NULL ) {
00857                 eurephia_log(ctx, LOG_FATAL, 0,
00858                              "eDBremove_sessionkey: Error removing sessionkey from openvpn_sessionkeys");
00859                 return 0;
00860         }
00861         sqlite_free_results(res);
00862         return 1;
00863 }
00864 
00868 eurephiaVALUES *eDBload_sessiondata(eurephiaCTX *ctx, const char *sesskey) {
00869         dbresult *res = NULL;
00870         eurephiaVALUES *sessvals = NULL;
00871         int i;
00872 
00873         if( (ctx == NULL) || (sesskey == NULL) ) {
00874                 return NULL;
00875         }
00876 
00877         DEBUG(ctx, 20, "Function call: eDBload_sessiondata(ctx, '%s')", sesskey);
00878 
00879         sessvals = eCreate_value_space(ctx, 10);
00880 
00881         res = sqlite_query(ctx, "SELECT datakey, dataval FROM openvpn_sessions WHERE sessionkey = '%q'",
00882                            sesskey);
00883         if( (res != NULL) || (sqlite_get_numtuples(res) > 0)  ) {
00884                 for( i = 0; i < sqlite_get_numtuples(res); i++ ) {
00885                         eAdd_value(ctx, sessvals, 
00886                                    sqlite_get_value(res, i, 0), 
00887                                    sqlite_get_value(res, i, 1));
00888                 }
00889         } else {
00890                 eurephia_log(ctx, LOG_CRITICAL, 0,
00891                              "Could not load session values for session '%s'", sesskey);
00892                 
00893         }
00894         sqlite_free_results(res);
00895         return sessvals;
00896 }
00897 
00901 int eDBstore_session_value(eurephiaCTX *ctx, eurephiaSESSION *session, int mode, const char *key, const char *val) 
00902 {
00903         dbresult *res = NULL;
00904 
00905         if( session == NULL ) {
00906                 DEBUG(ctx, 20,
00907                       "Function call failed to eDBstore_session_value(ctx, ...): Non-existing session key");
00908                 return 0;
00909         }
00910 
00911         DEBUG(ctx, 20, "Function call: eDBstore_session_value(ctx, '%s', %i, '%s', '%s')",
00912               session->sessionkey, mode, key, val);
00913 
00914         switch( mode ) {
00915         case SESSVAL_NEW:
00916                 res = sqlite_query(ctx,
00917                                    "INSERT INTO openvpn_sessions (sessionkey, datakey, dataval) "
00918                                    "VALUES ('%q','%q','%q')", session->sessionkey, key, val);
00919                 if( res == NULL ) {
00920                         eurephia_log(ctx, LOG_FATAL, 0,
00921                                      "Could not register new session variable into database: [%s] %s = %s",
00922                                      session->sessionkey, key, val);
00923                         return 0;
00924                 }
00925                 break;
00926 
00927         case SESSVAL_UPDATE:
00928                 res = sqlite_query(ctx,
00929                                    "UPDATE openvpn_sessions SET dataval = '%q' "
00930                                    " WHERE sessionkey = '%q' AND datakey = '%q'",
00931                                    val, session->sessionkey, key);
00932                 if( res == NULL ) {
00933                         eurephia_log(ctx, LOG_FATAL, 0, "Could not update session variable: [%s] %s = %s ",
00934                                      session->sessionkey, key, val);
00935                         return 0;
00936                 }
00937                 break;
00938 
00939         case SESSVAL_DELETE:
00940                 res = sqlite_query(ctx,
00941                                    "DELETE FROM openvpn_sessions "
00942                                    " WHERE sessionkey = '%q' AND datakey = '%q'",
00943                                    session->sessionkey, key);
00944                 if( res == NULL ) {
00945                         eurephia_log(ctx, LOG_FATAL, 0, "Could not delete session variable: [%s] %s",
00946                                      session->sessionkey, key);
00947                         return 0;
00948                 }
00949                 break;
00950 
00951         default:
00952                 eurephia_log(ctx, LOG_FATAL, 0, "Unknown eDBstore_session_value mode '%i'", mode);
00953                 return 0;
00954         }
00955         sqlite_free_results(res);
00956         return 1;
00957 }
00958 
00959 
00963 int eDBdestroy_session(eurephiaCTX *ctx, eurephiaSESSION *session) {
00964         dbresult *res = NULL;
00965         
00966         DEBUG(ctx, 20, "Function call: eDBdestroy_session(ctx, '%s')", session->sessionkey);
00967 
00968         if( (session == NULL) || (session->sessionkey == NULL) ) {
00969                 eurephia_log(ctx, LOG_WARNING, 1, "No active session given to be destroyed");
00970                 return 1;
00971         }
00972 
00973         // Update session status - if we have a "real" session (not auth-session)
00974         if( session->type == stSESSION ) {
00975                 res = sqlite_query(ctx,
00976                                    "UPDATE openvpn_lastlog "
00977                                    "   SET sessionstatus = 4, session_deleted = CURRENT_TIMESTAMP "
00978                                    " WHERE sessionkey = '%q' AND sessionstatus = 3", session->sessionkey);
00979                 if( res == NULL ) {
00980                         eurephia_log(ctx, LOG_FATAL, 0,
00981                                      "Could not update session status in lastlog (%s))", session->sessionkey);
00982                         return 0;
00983                 }
00984                 sqlite_free_results(res);
00985         }
00986 
00987         // Delete session variables
00988         res = sqlite_query(ctx, "DELETE FROM openvpn_sessions WHERE sessionkey = '%q'", session->sessionkey);
00989         if( res == NULL ) {
00990                 eurephia_log(ctx, LOG_FATAL, 0,
00991                              "Could not delete session variables (%s))", session->sessionkey);
00992                 return 0;
00993         }
00994         sqlite_free_results(res);
00995 
00996         // Remove the sessionkey from openvpn_sessions
00997         if( eDBremove_sessionkey(ctx, session->sessionkey) == 0 ) {
00998                 return 0;
00999         }
01000         return 1;
01001 }
01002 
01003 
01007 char *eDBget_firewall_profile(eurephiaCTX *ctx, eurephiaSESSION *session) 
01008 {
01009         char *ret = NULL;
01010         dbresult *res = NULL;
01011 
01012         DEBUG(ctx, 20, "Function call: eDBget_firewall_profile(ctx, {session}'%s')",
01013               session->sessionkey);
01014 
01015         res = sqlite_query(ctx,
01016                            "SELECT fw_profile "
01017                            "  FROM openvpn_lastlog "
01018                            "  JOIN openvpn_usercerts USING(certid, uid)"
01019                            "  JOIN openvpn_accesses USING(accessprofile)"
01020                            " WHERE sessionkey = '%q'", session->sessionkey);
01021         if( res == NULL ) {
01022                 eurephia_log(ctx, LOG_FATAL, 0, "Could not retrieve firewall profile for session '%s'",
01023                              session->sessionkey);
01024                 return NULL;
01025         }
01026         ret = strdup_nullsafe(sqlite_get_value(res, 0, 0));
01027         sqlite_free_results(res);
01028         return ret;
01029 }
01030 
01031 
01035 eurephiaVALUES *eDBget_blacklisted_ip(eurephiaCTX *ctx) {
01036         eurephiaVALUES *ret = NULL;
01037         dbresult *res = NULL;
01038         int i = 0;
01039         char *ip = NULL;
01040 
01041         DEBUG(ctx, 20, "Function call: eDBget_blacklisted_ip(ctx)");
01042 
01043         res = sqlite_query(ctx, "SELECT remoteip FROM openvpn_blacklist WHERE remoteip IS NOT NULL");
01044         if( res == NULL ) {
01045                 eurephia_log(ctx, LOG_FATAL, 0,
01046                              "Could not retrieve blacklisted IP addresses from the database");
01047                 return NULL;
01048         }
01049         ret = eCreate_value_space(ctx, 21);
01050         for( i = 0; i < sqlite_get_numtuples(res); i++ ) {
01051                 if( (ip = sqlite_get_value(res, i, 0)) != NULL ) {
01052                         eAdd_value(ctx, ret, NULL, ip);
01053                 }
01054         }
01055         sqlite_free_results(res);
01056 
01057         return ret;
01058 }
01059 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines