summaryrefslogtreecommitdiffstats
path: root/plugin/eurephia.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/eurephia.c')
-rw-r--r--plugin/eurephia.c58
1 files changed, 51 insertions, 7 deletions
diff --git a/plugin/eurephia.c b/plugin/eurephia.c
index 71181f5..eda014f 100644
--- a/plugin/eurephia.c
+++ b/plugin/eurephia.c
@@ -204,6 +204,12 @@ eurephiaCTX *eurephiaInit(const char const **argv, const char const **envp)
ctx->eurephia_fw_intf = NULL;
}
+ // Prepare an empty disconnected list.
+ // This one is used to track all clients IP addresses and their corresponding eurephia session ID
+ // when they disconnect. This is especially needed in TUN mode, the eurephia_learn_address()
+ // delete call with otherwise have too little information to identify the session.
+ ctx->disconnected = eCreate_value_space(ctx, 12);
+
eurephia_log(ctx, LOG_INFO, 1, "eurephia-auth is initialised");
return ctx;
}
@@ -223,6 +229,11 @@ int eurephiaShutdown(eurephiaCTX *ctx)
return 0;
}
+ if( ctx->disconnected != NULL ) {
+ eFree_values(ctx, ctx->disconnected);
+ ctx->disconnected = NULL;
+ }
+
if( ctx->eurephia_fw_intf != NULL ) {
if( ctx->fwcfg != NULL ) {
eFW_StopFirewall(ctx);
@@ -599,6 +610,12 @@ int eurephia_disconnect(eurephiaCTX *ctx, const char **env) {
return 0;
}
+ if( ctx->tuntype == tuntype_TUN ) {
+ // Put the clients IP address into the disconnected list, to be used and freed
+ // by eurephia_learn_address() afterwards
+ eAdd_value(ctx, ctx->disconnected, vpnipaddr, session->sessionkey);
+ }
+
ret = eDBregister_logout(ctx, session, bytes_sent, bytes_rec, duration);
eDBfree_session(ctx, session);
eurephia_log(ctx, LOG_INFO, 1, "User '%s' logged out", uname);
@@ -646,7 +663,7 @@ int eurephia_learn_address(eurephiaCTX *ctx, const char *mode, const char *clien
char *fwprofile = NULL, *fwdest = NULL;
int ret = 0, fw_enabled = 0;
- DEBUG(ctx, 10, "** Function call: eurephia_learn_address(ctx, '%.10s', '%.18s', ...)",
+ DEBUG(ctx, 10, "** Function call: eurephia_learn_address(ctx, '%.10s', '%.64s', ...)",
mode, clientaddr);
// Get firewall information
@@ -656,7 +673,15 @@ int eurephia_learn_address(eurephiaCTX *ctx, const char *mode, const char *clien
eurephia_log(ctx, LOG_CRITICAL, 0, "No firewall destination defined in the config.");
}
- if( strncmp(mode, "add", 3) == 0 ) {
+ // In TUN mode, if a client reconnects quickly after a disconnect,
+ // OpenVPN re-uses the session for this and just sends an update
+ // call to LEARN_ADDRESS. As eurephia in TUN mode treats disconnects
+ // with an explicit 'delete' (see eurephia-auth.c for more info) and
+ // don't wait for a separate LEARN_ADDRESS delete call (which never
+ // seems to come), we treat 'update' as an ordinary 'add' in TUN mode.
+ if( (strncmp(mode, "add", 3) == 0)
+ || ((ctx->tuntype == tuntype_TUN) && (strncmp(mode, "update", 6) == 0)) ) {
+
// Fetch needed info
digest = GETENV_TLSDIGEST(ctx, env, 0);
cname = GETENV_CNAME(ctx, env);
@@ -674,8 +699,12 @@ int eurephia_learn_address(eurephiaCTX *ctx, const char *mode, const char *clien
goto exit;
}
- // Update openvpn_lastlog with the active MAC address, and save it as a session variable
- ret = eDBregister_vpnmacaddr(ctx, session, clientaddr);
+ if( ctx->tuntype == tuntype_TAP ) {
+ // Update openvpn_lastlog with the active MAC address, and save it as a session variable
+ ret = eDBregister_vpnmacaddr(ctx, session, clientaddr);
+ } else {
+ ret = 1;
+ }
if( (fw_enabled) && (fwdest != NULL) ) {
fwprofile = eDBget_firewall_profile(ctx, session);
@@ -696,11 +725,26 @@ int eurephia_learn_address(eurephiaCTX *ctx, const char *mode, const char *clien
} else if( strncmp(mode, "delete", 6) == 0 ) {
- // Load the session, based on MAC address
- session = eDBopen_session_macaddr(ctx, clientaddr);
+ // Load the session
+ if( ctx->tuntype == tuntype_TAP ) {
+ // in TAP mode - use the MAC address
+ session = eDBopen_session_macaddr(ctx, clientaddr);
+ } else {
+ // in TUN mode - use the disconnected list to find the session key
+ eurephiaVALUES *sessval = eGet_valuestruct(ctx->disconnected, clientaddr);
+ if( sessval ) {
+ session = eDBsession_load(ctx, sessval->val, stSESSION);
+ if( ctx->disconnected->next != NULL ) {
+ ctx->disconnected = eRemove_value(ctx, ctx->disconnected,
+ sessval->evgid, sessval->evid);
+ } else {
+ eClear_key_value(ctx->disconnected);
+ }
+ }
+ }
if( session == NULL ) {
eurephia_log(ctx, LOG_WARNING, 0,
- "Could not find any session connected to this MAC address: %.18s",
+ "Could not find any session connected to the client address %s",
clientaddr);
ret = 0;
goto exit;