From fa6727f564debe32bc91cf1b18cabd19d489caef Mon Sep 17 00:00:00 2001 From: Arie Peterson <arie@greenhost.nl> Date: Wed, 21 Jun 2017 14:36:12 +0200 Subject: [PATCH] Resolve discussions of !3 --- src/api/encryption_add.c | 40 ++++++++++++++++++++++++++++++----- src/auxiliary.c | 8 +++++-- src/encryption_functions.c | 43 ++++++++++++++++++++------------------ 3 files changed, 64 insertions(+), 27 deletions(-) diff --git a/src/api/encryption_add.c b/src/api/encryption_add.c index 57132fb..554300d 100644 --- a/src/api/encryption_add.c +++ b/src/api/encryption_add.c @@ -1,5 +1,17 @@ /** * Callback function for encrypting an unencrypted device. + * It proceeds as follows: + * 1. check if the device isn't already encrypted; + * 2. mount the unencrypted device; + * 3. determine the total size of the files on the device, and guess if they + * will fit into memory; + * 4. rsync all files from the unencrypted device to memory; + * 5. unmount the unencrypted device; + * 6. initialise a new encrypted container on the same device, replacing the + unencrypted contents, and unlock it for use; + * 7. create a new filesystem inside the new container, and mount it; + * 8. rsync all files back from memory to this newly encrypted device; + * 9. unmount the new filesystem, and lock the encrypted container. * @param[in] request incoming HTTP request * @param[out] response HTTP response to the request * @param[in] user_data extra data to pass between main thread and callbacks @@ -20,25 +32,32 @@ int callback_encryption_add(const struct _u_request * request, } // Check if the device isn't already encrypted. - bool device_encrypted = is_encrypted_device(CONTAINER_DEVICE); - if (device_encrypted) + if (is_encrypted_device(CONTAINER_DEVICE)) { // The device is already encrypted; we don't want to encrypt it again. return send_simple_response(response, 500, "error", "already encrypted"); } - // Create temporary mountpoint. + // Mount the filesystem on the unencrypted device. r = temporary_mount(CONTAINER_DEVICE, UNENCRYPTED_MOUNTPOINT, FILESYSTEM_TYPE); if (r != 0) { + printf("mounting root disk failed: return code %d", r); return send_simple_response(response, 500, "error", "mounting root disk failed"); } // Determine the filesystem usage of the device to be encrypted. unsigned long size = filesystem_usage(UNENCRYPTED_MOUNTPOINT); + if (size < 0) + { + // Something went wrong in determining the filesystem usage. + printf("determining filesystem usage failed: return code %lu", size); + return send_simple_response(response, 500, "error", + "determining filesystem usage failed"); + } printf("root disk usage: %lu bytes\n", size); // Determine the available memory. @@ -60,8 +79,10 @@ int callback_encryption_add(const struct _u_request * request, r = system(command); if(r != 0) { + printf("copying rootdisk contents into memory failed: return code %d", + r); return send_simple_response(response, 500, "error", - "copying rootdisk contents into memory failed"); + "copying rootdisk contents into memory failed"); } // Unmount unencrypted device. @@ -69,15 +90,17 @@ int callback_encryption_add(const struct _u_request * request, r = umount(UNENCRYPTED_MOUNTPOINT); if (r != 0) { + printf("unmounting encrypted device failed: return code %d", r); return send_simple_response(response, 500, "error", "unmounting unencrypted disk failed"); } // Initialise encrypted container, overwriting existing device. - printf("creating encrypted device at %s\n", CONTAINER_DEVICE); + printf("creating encrypted container at %s\n", CONTAINER_DEVICE); r = create_encrypted_device(CONTAINER_DEVICE, password); if(r != 0) { + printf("creating encrypted container failed: return code %d", r); return send_simple_response(response, 500, "error", "creating encryption container failed"); } @@ -87,6 +110,7 @@ int callback_encryption_add(const struct _u_request * request, r = encryption_unlock(CONTAINER_DEVICE, MAPPED_DEVICE_NAME, password); if(r != 0) { + printf("unlocking encrypted container failed: return code %d", r); return send_simple_response(response, 500, "error", "unlocking new encryption container failed"); } @@ -98,6 +122,7 @@ int callback_encryption_add(const struct _u_request * request, r = system(command); if(r != 0) { + printf("creating filesystem failed: return code %d", r); return send_simple_response(response, 500, "error", "creating filesystem inside encrypted container failed"); } @@ -108,6 +133,7 @@ int callback_encryption_add(const struct _u_request * request, FILESYSTEM_TYPE); if (r != 0) { + printf("mounting encrypted disk failed: return code %d", r); return send_simple_response(response, 500, "error", "mounting encrypted root disk failed"); } @@ -119,6 +145,8 @@ int callback_encryption_add(const struct _u_request * request, r = system(command); if(r != 0) { + printf("copying from memory to encrypted disk failed: return code %d", + r); return send_simple_response(response, 500, "error", "copying rootdisk contents from memory failed"); } @@ -128,6 +156,7 @@ int callback_encryption_add(const struct _u_request * request, r = umount(ENCRYPTED_MOUNTPOINT); if (r != 0) { + printf("unmounting encrypted disk failed: return code %d", r); return send_simple_response(response, 500, "error", "unmounting encrypted disk failed"); } @@ -137,6 +166,7 @@ int callback_encryption_add(const struct _u_request * request, r = encryption_lock(MAPPED_DEVICE_NAME); if(r != 0) { + printf("locking encrypted container failed: return code %d", r); return send_simple_response(response, 500, "error", "locking container failed"); } diff --git a/src/auxiliary.c b/src/auxiliary.c index 722b358..fcbcde6 100644 --- a/src/auxiliary.c +++ b/src/auxiliary.c @@ -98,12 +98,16 @@ unsigned long available_memory() /** * Determine the usage of the given filesystem. * @param path Path of the mounted filesystem. - * @return Number of bytes used. + * @return Number of bytes used, or -1 in case of failure. */ unsigned long filesystem_usage(const char * path) { struct statvfs s; - statvfs(path, &s); + int r = statvfs(path, &s); + if (r != 0) + { + return -1; + } return (s.f_blocks - s.f_bfree) * s.f_bsize; } diff --git a/src/encryption_functions.c b/src/encryption_functions.c index 313b65c..7f1f842 100644 --- a/src/encryption_functions.c +++ b/src/encryption_functions.c @@ -4,16 +4,21 @@ * seems usable. * @param crypt_device struct to store crypt device context * @param crypt_device path to the encrypted container + * @param debug whether to print debug messages * @return status code */ -static int container_initialise(struct crypt_device **cd, const char *path) +static int container_initialise(struct crypt_device ** cd, const char * path, + const bool debug) { // Let LUKS initialise the encrypted device. int r = crypt_init(cd, path); if (r < 0) { - printf("crypt_init() failed for %s.\n", path); - printf("status: %d.\n", r); + if (debug) + { + printf("crypt_init() failed for %s.\n", path); + printf("status: %d.\n", r); + } return r; } @@ -21,8 +26,11 @@ static int container_initialise(struct crypt_device **cd, const char *path) r = crypt_load(*cd, CRYPT_LUKS1, NULL); if (r < 0) { - printf("crypt_load() failed on device %s.\n", - crypt_get_device_name(*cd)); + if (debug) + { + printf("crypt_load() failed on device %s.\n", + crypt_get_device_name(*cd)); + } } return r; @@ -32,18 +40,13 @@ static int container_initialise(struct crypt_device **cd, const char *path) * Check if the given device is actually an encrypted container. * @param path path to the encrypted container */ -static bool is_encrypted_device (const char *path) +static bool is_encrypted_device(const char * path) { // Let LUKS initialise the encrypted device. - struct crypt_device *cd; - int r = container_initialise(&cd, path); + struct crypt_device * cd; + int r = container_initialise(&cd, path, false); crypt_free(cd); - if (r < 0) - { - return false; - } - - return true; + return (r >= 0); } /** @@ -54,12 +57,12 @@ static bool is_encrypted_device (const char *path) * @param password encryption password of the container * @return status code */ -static int encryption_unlock(const char *path, const char *device_name, - const char *password) +static int encryption_unlock(const char * path, const char * device_name, + const char * password) { // Let LUKS initialise the encrypted device. - struct crypt_device *cd; - int r = container_initialise(&cd, path); + struct crypt_device * cd; + int r = container_initialise(&cd, path, true); if (r < 0) { printf("crypt_load() failed on device %s.\n", @@ -92,9 +95,9 @@ static int encryption_unlock(const char *path, const char *device_name, * @param device_name name of the mapping * @return status code */ -static int encryption_lock(const char *device_name) +static int encryption_lock(const char * device_name) { - struct crypt_device *cd; + struct crypt_device * cd; int r; r = crypt_init_by_name(&cd, device_name); -- GitLab