From 7a951c980f07d74c830b8c002bc8a8cd5454b87a Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Wed, 1 Mar 2023 19:52:44 +0000 Subject: [PATCH] Cleanup old user interactive auth sessions. --- TODO.txt | 4 ++-- src/Db.c | 12 +++++++----- src/Uia.c | 38 +++++++++++++++++++++++++++++++++++--- src/include/Db.h | 2 +- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/TODO.txt b/TODO.txt index 581b0bb..2eea4e6 100644 --- a/TODO.txt +++ b/TODO.txt @@ -24,10 +24,10 @@ Milestone: v0.2.0 [x] Delete refresh token if present [ ] Logout all [x] Login fallback (static HTML page) -[~] User Interactive +[x] User Interactive [x] Passwords [x] Caller builds flows - [ ] Clean up old sessions + [x] Clean up old sessions [ ] Document new User functions [ ] Document new JSON functions diff --git a/src/Db.c b/src/Db.c index 1168f67..90c1f8d 100644 --- a/src/Db.c +++ b/src/Db.c @@ -802,9 +802,9 @@ DbList(Db * db, size_t nArgs,...) { Array *result; Array *path; - DIR* files; - struct dirent* file; - char* dir; + DIR *files; + struct dirent *file; + char *dir; va_list ap; if (!db || !nArgs) @@ -829,10 +829,12 @@ DbList(Db * db, size_t nArgs,...) Free(dir); return NULL; } - while((file = readdir(files))) { + while ((file = readdir(files))) + { if (file->d_type == DT_REG && file->d_namlen > 5) { int nameOffset = file->d_namlen - 5; + if (strcmp(file->d_name + nameOffset, ".json") == 0) { file->d_name[nameOffset] = '\0'; @@ -849,7 +851,7 @@ DbList(Db * db, size_t nArgs,...) } void -DbListFree(Array *arr) +DbListFree(Array * arr) { StringArrayFree(arr); } diff --git a/src/Uia.c b/src/Uia.c index d52cb7e..fc6d831 100644 --- a/src/Uia.c +++ b/src/Uia.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -132,6 +133,7 @@ BuildResponse(Array * flows, Db * db, HashMap ** response, char *session, DbRef json = DbJson(ref); HashMapSet(json, "completed", JsonValueArray(ArrayCreate())); + HashMapSet(json, "last_access", JsonValueInteger(UtilServerTs())); DbUnlock(db, ref); HashMapSet(*response, "completed", JsonValueArray(ArrayCreate())); @@ -416,6 +418,7 @@ UiaComplete(Array * flows, HttpServerContext * context, Db * db, finish: ArrayFree(possibleNext); + JsonValueFree(HashMapSet(dbJson, "last_access", JsonValueInteger(UtilServerTs()))); DbUnlock(db, dbRef); return ret; } @@ -451,9 +454,38 @@ UiaFlowsFree(Array * flows) void UiaCleanup(MatrixHttpHandlerArgs * args) { - Log(args->lc, LOG_DEBUG, "Purging old user interactive auth sessions..."); - if (!DbDelete(args->db, 1, "user_interactive")) + Array *sessions = DbList(args->db, 1, "user_interactive"); + size_t i; + + Log(args->lc, LOG_DEBUG, "User Interactive Auth sessions: %lu", + ArraySize(sessions)); + for (i = 0; i < ArraySize(sessions); i++) { - Log(args->lc, LOG_ERR, "Failed to purge user_interactive."); + char *session = ArrayGet(sessions, i); + DbRef *ref = DbLock(args->db, 2, "user_interactive", session); + + unsigned long lastAccess; + + if (!ref) + { + Log(args->lc, LOG_ERR, "Unable to lock uia %s for inspection.", + session); + continue; + } + + lastAccess = JsonValueAsInteger(HashMapGet(DbJson(ref), "last_access")); + + /* If last access was greater than 15 minutes ago, remove this + * session */ + if (UtilServerTs() - lastAccess > 1000 * 60 * 15) + { + DbUnlock(args->db, ref); + DbDelete(args->db, 2, "user_interactive", session); + Log(args->lc, LOG_DEBUG, "Deleted session %s", session); + } + + DbUnlock(args->db, ref); } + + DbListFree(sessions); } diff --git a/src/include/Db.h b/src/include/Db.h index 4be8b07..b77c74f 100644 --- a/src/include/Db.h +++ b/src/include/Db.h @@ -61,7 +61,7 @@ extern Array * DbList(Db *, size_t,...); extern void -DbListFree(Array *); + DbListFree(Array *); extern HashMap * DbJson(DbRef *);