summaryrefslogtreecommitdiffstats
path: root/plugin/eurephia.c
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2009-01-03 21:53:07 +0100
committerDavid Sommerseth <dazo@users.sourceforge.net>2009-01-03 21:53:07 +0100
commit8a0b87ab7e99af1700aa80cb54373b68864eb0d4 (patch)
tree54e05e1eb91efffb5268dce49368e756ed58d7a7 /plugin/eurephia.c
parent241b14d771d247127508cf7b20f833b9dbe0abda (diff)
downloadeurephia-8a0b87ab7e99af1700aa80cb54373b68864eb0d4.tar.gz
eurephia-8a0b87ab7e99af1700aa80cb54373b68864eb0d4.tar.xz
eurephia-8a0b87ab7e99af1700aa80cb54373b68864eb0d4.zip
Introduced password caching on authenticated sessions
This is to prepare eurephia-auth plugin to use other and more CPU intensive hashing algorithms for passwords. In addition, open sessions will now not be rejected/closed due to wrong password if the user changes the password with an open session running. The patch adds a new server_salt attribute in the eurephiaCTX structure. This is used as a temporary salt and is created of random data when OpenVPN is started. When a user is being authenticated (eurephia.c/eurephia_userauth) a authentication session (not the same as a 'normal' session) is opened and checked for a cached password. If it does not exist or match, normal password check will be done against the user database. If a cached password is found and matches, it is considered to be authenticated. The cached password uses the SHA512 algorithm, together with the eurephiaCTX->server_salt.
Diffstat (limited to 'plugin/eurephia.c')
-rw-r--r--plugin/eurephia.c68
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;
}