#define _GNU_SOURCE #include "encryption.h" #include "shared.h" #include #include #include #include #include #include #include #include #include #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 void naclfaildefault(void *none) { none = none; // Makes gcc happy error(1, ENOTSUP, "Couldn't initialize sodium for some reason. Quitting..."); } int checksodiumcb(const vxgg_naclfailcb callback, void *data) { static vxgg_naclfailcb cb = naclfaildefault; static void *usr = NULL; if(callback != NULL) { cb = callback; usr = data; return 2; // libsodium normally returns 1 if the library is already initialized, so this is to signal that the callback has been updated } int ret = sodium_init(); if(ret < 0) cb(usr); return ret; } void vxgg_setsodiumfailcb(vxgg_naclfailcb cb, void *data) { checksodiumcb(cb, data); } #endif void checksodium(void) { #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 checksodiumcb(NULL, NULL); #else if(sodium_init() < 0) error(1, ENOTSUP, "Couldn't initialize sodium for some reason. Quitting..."); #endif return; } // To encrypt: // 1- Create a temp file with the correct name in the root folder of the partition being encrypted -- // 1.1- Detect the partition and find the root folder -- DONE || NOT NECESSARY // 1.2- Create the temp file -- DONE // 2- Encrypt the file's contents to the temp file -- // 2.1- Open the file -- // 2.2- Stream the file's contents into some encryption algo -- // 2.3- Pipe the output of the encryption into the temp file -- // 3- Once the file has been encrypted, hard link it back to the original location, with the right name -- // 4- Delete the original file -- // 5- Delete the temp file -- int maketmp(const char *dest) { return open(dest, (O_TMPFILE | O_WRONLY | O_CLOEXEC | O_SYNC), (S_IRUSR | S_IWUSR)); } int encrypttotmp(const char *toencrypt) { #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 checksodium(); #endif struct stat esb; int efd = -1; // Make sure the file is real and an actual file that can be encrypted if(stat(toencrypt, &esb) < 0) return -1; if(!S_ISREG(esb.st_mode)) return -2; // Open the file as read-only if((efd = open(toencrypt, O_RDONLY)) < 0) return -3; // Need to get a secret key from a password and then set up cryptostream from libsodium return 0; } int genpassword(char **str, unsigned int words) { // Early returns if(words < 1) return 0; #if defined ___VXGG___ALWAYS_CHECK_LIBSODIUM___ && ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 checksodium(); #endif // Bootstrap the first word char *lstr = NULL, *tmp = NULL; if(asprintf(&lstr, "%s", PASSWORD_WORDS[randombytes_uniform(PASSWORD_WORDS_LEN)]) < 0) return -1; // Concat the rest of the words into the password (without leaking memory) int ret; for(unsigned int i = 1; i < words; i++) { ret = asprintf(&tmp, "%s %s", lstr, PASSWORD_WORDS[randombytes_uniform(PASSWORD_WORDS_LEN)]); free(lstr); if(ret < 0) return -1; lstr = tmp; } *str = lstr; return words; // This function was exploding because of some weird conflict with using my buggy implementation of asprintf instead of the // _GNU_SOURCE version. Don't know why it wasn't using the _GNU_SOURCE version, as I had a define macro put in place to // prevent it from being compiled if _GNU_SOURCE was defined, but whatever } #define TESTING #ifdef TESTING #include int main(void) { /*// Example code for creating a temp file, writing to it, then linking it back into the fs const char *dir = ".", *testmsg = "we do a little testing\n"; char *path = NULL; int fd = maketmp(dir); if(fd < 0) error(1, errno, "Couldn't make temp file at %s", dir); if(write(fd, testmsg, strlen(testmsg)) < 0) error(1, errno, "write broke"); asprintf(&path, "/proc/self/fd/%d", fd); linkat(AT_FDCWD, path, AT_FDCWD, "./test", AT_SYMLINK_FOLLOW); free(path); // Apparently, I don't have the CAP_DAC_READ_SEARCH capibility. Thanks for the solution, linux man pages if(close(fd) < 0) error(1, errno, "close broke"); //*/// //*// Example code for getting a password using genpassword checksodium(); char *password = NULL; genpassword(&password, 20); printf("%s\n", (password != NULL) ? password : "Couldn't get a password"); free(password); //*/// return 0; } #endif