diff options
Diffstat (limited to 'plugin/eurephia.c')
-rw-r--r-- | plugin/eurephia.c | 68 |
1 files changed, 64 insertions, 4 deletions
diff --git a/plugin/eurephia.c b/plugin/eurephia.c index 2d50fc0..06394a2 100644 --- a/plugin/eurephia.c +++ b/plugin/eurephia.c @@ -34,6 +34,7 @@ #include <eurephiadb_session_common.h> #include <eurephiadb_session.h> #include <certinfo.h> +#include <passwd.h> #define MAX_ARGUMENTS 64 @@ -193,6 +194,19 @@ eurephiaCTX *eurephiaInit(const char **argv) return NULL; } + // Get data for server_salt - which will be used for the password cache + ctx->server_salt = (char *) malloc(SIZE_PWDCACHE_SALT+2); + memset(ctx->server_salt, 0, SIZE_PWDCACHE_SALT+2); + if( !eDBsessionGetRandString(ctx, ctx->server_salt, SIZE_PWDCACHE_SALT) ) { + eurephia_log(ctx, LOG_PANIC, 0 , "Could not get enough random data for password cache."); + + free_nullsafe(ctx->server_salt); + eDBdisconnect(ctx); + fclose(ctx->log); + free_nullsafe(ctx); + return NULL; + } + // Check if firewall functionality is enabled, load module if given fwintf = eGet_value(ctx->dbc->config, "firewall_interface"); if( fwintf != NULL ) { @@ -307,9 +321,11 @@ int eurephia_tlsverify(eurephiaCTX *ctx, const char **env, const char *depth) int eurephia_userauth(eurephiaCTX *ctx, const char **env) { + eurephiaSESSION *authsess = NULL; int result = 0, certid = 0; - char *ipaddr; - char *tls_digest, *tls_id, *username, *passwd; + const char *cname, *remport, *ipaddr = NULL; + const char *tls_digest = NULL, *tls_id = NULL, *username = NULL; + char *passwd = NULL, *pwdcache = NULL, *chkpwd = NULL; certinfo *ci = NULL; DEBUG(ctx, 10, "** Function call: eurephia_userauth(...)"); @@ -359,6 +375,38 @@ int eurephia_userauth(eurephiaCTX *ctx, const char **env) // Do username/password/certificate authentication passwd = (char *)get_env(ctx, 1, env, "password"); + if( (passwd == NULL) || (strlen_nullsafe(passwd) == 0) ) { + eurephia_log(ctx, LOG_WARNING, 0, "eurephia-auth: No password received. Action aborted"); + free_certinfo(ci); + return 0; + } + + // Check if we have a valid password cached + chkpwd = passwdhash(pwdSHA512, ctx->server_salt, passwd); + + // Get an authentication session, which is not a real session ticket + // but it uses almost the same system + cname = get_env(ctx, 0, env, "common_name"); + remport = get_env(ctx, 0, env, "untrusted_port"); + + // an authentication session do not use assigned VPN address + authsess = eDBopen_session_seed(ctx, tls_digest, cname, username, NULL, NULL, ipaddr, remport); + if( authsess == NULL ) { + // No session found + goto chk_pwd; + } + // Get cached password from password cache + pwdcache = eGet_value(authsess->sessvals, "pwdcache"); + + if( (pwdcache != NULL) && (chkpwd != NULL) && (strcmp(pwdcache, chkpwd) == 0) ) { + // if cached password matches users password, we're done + eurephia_log(ctx, LOG_INFO, 3, "Authenticated user '%s' against password cache", username); + result = 1; + goto exit; + } + + // If we do not have a valid password cached, check against the user database + chk_pwd: result = eDBauth_user(ctx, certid, username, passwd); if( result < 1 ) { eDBregister_attempt(ctx, attempt_IPADDR, ATTEMPT_REGISTER, ipaddr); @@ -366,15 +414,21 @@ int eurephia_userauth(eurephiaCTX *ctx, const char **env) eDBregister_attempt(ctx, attempt_USERNAME, ATTEMPT_REGISTER, username); } - if( result > 0 ) { // If we have a valid result, reset all attempt counters. eDBregister_attempt(ctx, attempt_IPADDR, ATTEMPT_RESET, ipaddr); eDBregister_attempt(ctx, attempt_CERTIFICATE, ATTEMPT_RESET, tls_digest); eDBregister_attempt(ctx, attempt_USERNAME, ATTEMPT_RESET, username); + if( !eDBset_session_value(ctx, authsess, "pwdcache", chkpwd) ) { + eurephia_log(ctx, LOG_WARNING, 0, "Failed to cache password for user '%s'", username); + } eurephia_log(ctx, LOG_INFO, 0, "User '%s' authenticated", username); } + + exit: + free_nullsafe(chkpwd); + eDBfree_session(ctx, authsess); DEBUG(ctx, 10, "** Function result: eurephia_userauth(...) = %i", (result>0)); return (result > 0); } @@ -452,11 +506,17 @@ int eurephia_disconnect(eurephiaCTX *ctx, const char **env) { return 0; } - // 2. eDBregister_logout(ctx, session, env[bytes_sent], env[bytes_received]) ret = eDBregister_logout(ctx, session, bytes_sent, bytes_rec, duration); eDBfree_session(ctx, session); eurephia_log(ctx, LOG_INFO, 1, "User '%s' is logged out", uname); + // Get the authentication session and destroy it + session = eDBopen_session_seed(ctx, digest, cname, uname, NULL, NULL, remipaddr, remport); + if( !eDBdestroy_session(ctx, session) ) { + eurephia_log(ctx, LOG_WARNING, 0, "Could not destroy authentication session (%s/%s/%s)", + uname, cname, digest); + } + DEBUG(ctx, 10, "** Function result: eurephia_disconnect(...) = %i", ret); return ret; } |