From 67e416e9ea9685715e4acf9c14ef60d5e1622a37 Mon Sep 17 00:00:00 2001
From: Arie Peterson <arie@greenhost.nl>
Date: Thu, 29 Jun 2017 16:03:18 +0200
Subject: [PATCH] Resolve discussions

---
 src/api/encryption_add.c    | 146 ++++++++++++++++++------------------
 src/api/encryption_unlock.c |   2 +-
 src/auxiliary.c             |   6 +-
 src/includes/settings.h     |   9 +--
 4 files changed, 82 insertions(+), 81 deletions(-)

diff --git a/src/api/encryption_add.c b/src/api/encryption_add.c
index bb5ea56..44faf35 100644
--- a/src/api/encryption_add.c
+++ b/src/api/encryption_add.c
@@ -6,22 +6,22 @@
  * 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.  collect existing authorised ssh keys from the root disk;
- * 6.  repartition the disk:
- *     . a small partition to hold unencrypted data for use from the initrd,
+ * 5.  check if an authorized_keys file can be found on the root device;
+ * 6.  unmount the unencrypted device;
+ * 7.  repartition the device:
+ *     . an info partition to hold unencrypted data for use from the initrd,
  *       like the dropbear ssh host keys and user's ssh public keys;
- *     . a big partition for the actual encrypted root disk;
- * 7.  create a filesystem on the first partition;
- * 8.  generate ssh host keys for dropbear;
- * 9.  copy these new ssh host keys and the authorised ssh keys collected
- *     earlier onto the small partition.
- * 10. unmount the unencrypted device;
- * 11. initialise a new encrypted container on the same device, replacing the
- *     unencrypted contents, and unlock it for use;
- * 12. create a new filesystem inside the new container, and mount it;
- * 13. rsync all files back from memory to this newly encrypted device;
- * 14. unmount the new filesystem, and lock the encrypted container;
- * 15. reboot.
+ *     . a data partition for the actual encrypted root device;
+ * 8.  create a filesystem on the info partition;
+ * 9.  copy ssh host keys and the authorized_keys file from the initrd
+ *     to the info partition;
+ * 10. initialise a new encrypted container on the data partition, and unlock it
+ *     for use;
+ * 11. create a new filesystem on this new encrypted data partition,
+ *     and mount it;
+ * 12. rsync all files back from memory to the encrypted data partition;
+ * 13. unmount the new filesystem, and lock the encrypted container;
+ * 14. reboot.
  * @param[in]   request   incoming HTTP request
  * @param[out]  response  HTTP response to the request
  * @param[in]   user_data extra data to pass between handler and main thread
@@ -55,9 +55,9 @@ int callback_encryption_add(const struct _u_request * request,
         FILESYSTEM_TYPE);
     if (r != 0)
     {
-        printf("mounting root disk failed: return code %d\n", r);
+        printf("mounting root device failed: return code %d\n", r);
         return send_simple_response(response, 500, "error",
-           "mounting root disk failed");
+           "mounting root device failed");
     }
 
     // Determine the filesystem usage of the device to be encrypted.
@@ -69,7 +69,7 @@ int callback_encryption_add(const struct _u_request * request,
         return send_simple_response(response, 500, "error",
            "determining filesystem usage failed");
     }
-    printf("root disk usage: %lu bytes\n", size);
+    printf("root device usage: %lu bytes\n", size);
 
     // Determine the available memory.
     unsigned long memory = available_memory();
@@ -84,16 +84,16 @@ int callback_encryption_add(const struct _u_request * request,
     }
 
     // Copy device contents to temporary filesystem.
-    printf("copying existing root disk contents to memory\n");
+    printf("copying existing root device contents to memory\n");
     char * command = NULL;
     asprintf(&command, "rsync -a %s/ %s", UNENCRYPTED_MOUNTPOINT, TMP_LOCATION);
     r = system(command);
     if(r != 0)
     {
-        printf("copying rootdisk contents into memory failed: return code %d\n",
-            r);
+        printf("copying root device contents into memory failed"
+            ": return code %d\n", r);
         return send_simple_response(response, 500, "error",
-            "copying rootdisk contents into memory failed");
+            "copying root device contents into memory failed");
     }
 
     // Unmount unencrypted device.
@@ -103,20 +103,20 @@ int callback_encryption_add(const struct _u_request * request,
     {
         printf("unmounting encrypted device failed: return code %d\n", r);
         return send_simple_response(response, 500, "error",
-           "unmounting unencrypted disk failed");
+           "unmounting unencrypted device failed");
     }
 
     // Check whether the authorized_keys file exists on root device.
     char * authorized_keys_path = NULL;
-    asprintf(&authorized_keys_path, "%s/root/.ssh/authorized_keys",
-        TMP_LOCATION);
+    asprintf(&authorized_keys_path, "%s%s",
+        TMP_LOCATION, AUTHORIZED_KEYS_PATH);
     struct stat st = {0};
     if (stat(authorized_keys_path, &st) == -1)
     {
-        printf("authorized_keys not found on root disk at %s\n",
+        printf("authorized_keys not found on root device at %s\n",
             authorized_keys_path);
         return send_simple_response(response, 500, "error",
-           "authorized_keys not found on root disk");
+           "authorized_keys not found on root device");
     }
 
     // Re-partition device.
@@ -146,15 +146,13 @@ int callback_encryption_add(const struct _u_request * request,
     // This seems necessary for the newly created partitions to appear as
     // devices.
     printf("waiting a bit...\n");
-    command = NULL;
-    asprintf(&command, "sleep 2");
-    r = system(command);
+    sleep(2);
 
-    // Create filesystem on the small partition.
-    printf("creating filesystem on unencrypted partition\n");
+    // Create filesystem on the info partition.
+    printf("creating filesystem on info partition\n");
     command = NULL;
     asprintf(&command, "mkfs -t %s %s", FILESYSTEM_TYPE,
-        ROOT_SMALL_PARTITION_DEVICE);
+        INFO_PARTITION_DEVICE);
     printf("command: %s\n", command);
     r = system(command);
     if (r != 0)
@@ -164,59 +162,59 @@ int callback_encryption_add(const struct _u_request * request,
            "creating filesystem inside encrypted container failed");
     }
 
-    // Mount the small partition.
-    printf("mounting small partition\n");
-    r = temporary_mount(ROOT_SMALL_PARTITION_DEVICE, SMALL_MOUNTPOINT,
+    // Mount the info partition.
+    printf("mounting info partition\n");
+    r = temporary_mount(INFO_PARTITION_DEVICE, INFO_MOUNTPOINT,
         FILESYSTEM_TYPE);
     if (r != 0)
     {
-        printf("mounting encrypted disk failed: return code %d\n", r);
+        printf("mounting encrypted device failed: return code %d\n", r);
         return send_simple_response(response, 500, "error",
-           "mounting encrypted root disk failed");
+           "mounting encrypted root device failed");
     }
 
-    // Create some directories in the small partition.
-    printf("creating directories in small partition\n");
+    // Create some directories in the info partition.
+    printf("creating directories in info partition\n");
     command = NULL;
-    asprintf(&command, "mkdir -p %s%s %s%s", SMALL_MOUNTPOINT,
-        AUTHORIZED_KEYS_DIR, SMALL_MOUNTPOINT, SSH_HOST_KEY_DIR);
+    asprintf(&command, "mkdir -p %s%s %s%s", INFO_MOUNTPOINT,
+        AUTHORIZED_KEYS_DIR, INFO_MOUNTPOINT, SSH_HOST_KEY_DIR);
     r = system(command);
     if (r != 0)
     {
         printf("creating directories failed: return code %d\n", r);
         return send_simple_response(response, 500, "error",
-           "creating directories in small partition failed");
+           "creating directories in info partition failed");
     }
 
-    // Copy authorized_keys file to the small partition.
-    printf("copying authorized_keys to small partition\n");
+    // Copy authorized_keys file to the info partition.
+    printf("copying authorized_keys to info partition\n");
     command = NULL;
-    asprintf(&command, "cp %s%s %s%s", TMP_LOCATION,
-        AUTHORIZED_KEYS_PATH, SMALL_MOUNTPOINT, AUTHORIZED_KEYS_PATH);
+    asprintf(&command, "cp %s %s%s",
+        AUTHORIZED_KEYS_PATH, INFO_MOUNTPOINT, AUTHORIZED_KEYS_PATH);
     r = system(command);
     if (r != 0)
     {
         printf("copying authorized_keys failed: return code %d\n", r);
         return send_simple_response(response, 500, "error",
-           "creating filesystem inside encrypted container failed");
+           "copying authorized_keys failed");
     }
 
-    // Generate ssh host key and put it in the small partition.
-    printf("generating ssh host key\n");
+    // Copy dropbear ssh host keys from the initrd to the info partition.
+    printf("copying dropbear ssh host keys\n");
     command = NULL;
-    asprintf(&command, "dropbearkey -t rsa -f %s%s", SMALL_MOUNTPOINT,
-        SSH_HOST_KEY_PATH);
+    asprintf(&command, "cp /etc/dropbear/* %s%s/", INFO_MOUNTPOINT,
+        SSH_HOST_KEY_DIR);
     r = system(command);
     if (r != 0)
     {
-        printf("generating ssh host key failed: return code %d\n", r);
+        printf("copying dropbear ssh host keys failed: return code %d\n", r);
         return send_simple_response(response, 500, "error",
-           "generating ssh host key failed");
+           "copying dropbear ssh host keys failed");
     }
 
-    // Unmount small partition device.
-    printf("unmounting small partition at %s\n", SMALL_MOUNTPOINT);
-    r = umount(SMALL_MOUNTPOINT);
+    // Unmount info partition.
+    printf("unmounting info partition at %s\n", INFO_MOUNTPOINT);
+    r = umount(INFO_MOUNTPOINT);
     if (r != 0)
     {
         printf("unmounting failed: return code %d\n", r);
@@ -224,9 +222,9 @@ int callback_encryption_add(const struct _u_request * request,
            "unmounting configuration partition failed");
     }
 
-    // Initialise encrypted container, overwriting existing device.
-    printf("creating encrypted container at %s\n", ROOT_BIG_PARTITION_DEVICE);
-    r = create_encrypted_device(ROOT_BIG_PARTITION_DEVICE, password);
+    // Initialise encrypted container on data partition.
+    printf("creating encrypted container at %s\n", DATA_PARTITION_DEVICE);
+    r = create_encrypted_device(DATA_PARTITION_DEVICE, password);
     if (r != 0)
     {
         printf("creating encrypted container failed: return code %d\n", r);
@@ -236,7 +234,7 @@ int callback_encryption_add(const struct _u_request * request,
 
     // Unlock the new container.
     printf("unlocking encrypted device\n");
-    r = encryption_unlock(ROOT_BIG_PARTITION_DEVICE, MAPPED_DEVICE_NAME,
+    r = encryption_unlock(DATA_PARTITION_DEVICE, MAPPED_DEVICE_NAME,
         password);
     if (r != 0)
     {
@@ -259,36 +257,36 @@ int callback_encryption_add(const struct _u_request * request,
 
     // Mount the unlocked container.
     printf("mounting new filesystem\n");
-    r = temporary_mount(MAPPED_DEVICE_PATH, BIG_MOUNTPOINT,
+    r = temporary_mount(MAPPED_DEVICE_PATH, DATA_MOUNTPOINT,
         FILESYSTEM_TYPE);
     if (r != 0)
     {
-        printf("mounting encrypted disk failed: return code %d\n", r);
+        printf("mounting encrypted device failed: return code %d\n", r);
         return send_simple_response(response, 500, "error",
-           "mounting encrypted root disk failed");
+           "mounting encrypted root device failed");
     }
 
     // Copy device contents from temporary filesystem to encrypted container.
-    printf("copying root disk contents from memory\n");
+    printf("copying root device contents from memory\n");
     command = NULL;
-    asprintf(&command, "rsync -a %s/ %s", TMP_LOCATION, BIG_MOUNTPOINT);
+    asprintf(&command, "rsync -a %s/ %s", TMP_LOCATION, DATA_MOUNTPOINT);
     r = system(command);
     if (r != 0)
     {
-        printf("copying from memory to encrypted disk failed: return code %d\n",
-            r);
+        printf("copying from memory to encrypted device failed:"
+            " return code %d\n", r);
         return send_simple_response(response, 500, "error",
-           "copying rootdisk contents from memory failed");
+           "copying root device contents from memory failed");
     }
 
-    // Unmount encrypted device.
-    printf("unmounting encrypted device at %s\n", BIG_MOUNTPOINT);
-    r = umount(BIG_MOUNTPOINT);
+    // Unmount filesystem on encrypted data partition.
+    printf("unmounting encrypted device at %s\n", DATA_MOUNTPOINT);
+    r = umount(DATA_MOUNTPOINT);
     if (r != 0)
     {
-        printf("unmounting encrypted disk failed: return code %d\n", r);
+        printf("unmounting encrypted device failed: return code %d\n", r);
         return send_simple_response(response, 500, "error",
-           "unmounting encrypted disk failed");
+           "unmounting encrypted device failed");
     }
 
     // Lock the container.
diff --git a/src/api/encryption_unlock.c b/src/api/encryption_unlock.c
index 86caee5..fd20287 100644
--- a/src/api/encryption_unlock.c
+++ b/src/api/encryption_unlock.c
@@ -18,7 +18,7 @@ int callback_encryption_unlock(const struct _u_request * request,
         return send_simple_response(response, 400, "error", "missing password");
     }
   
-    int unlock_status = encryption_unlock(ROOT_BIG_PARTITION_DEVICE,
+    int unlock_status = encryption_unlock(DATA_PARTITION_DEVICE,
         MAPPED_DEVICE_NAME, password);
   
     if (unlock_status == -1)
diff --git a/src/auxiliary.c b/src/auxiliary.c
index 62ec6ac..6226e2a 100644
--- a/src/auxiliary.c
+++ b/src/auxiliary.c
@@ -132,6 +132,10 @@ int temporary_mount(char * device_path, char * mount_path,
     return r;
 }
 
+/**
+ * Reboot the system. We cannot simply use the `reboot` command because
+ * we're running as init (pid 0).
+ */
 void reboot_initrd()
 {
     pid_t pid;
@@ -139,7 +143,7 @@ void reboot_initrd()
     if (pid == 0)
     {
         // Child.
-        reboot(0x1234567);
+        reboot(RB_AUTOBOOT);
         _exit(EXIT_SUCCESS);
     }
     // Parent (init) waits.
diff --git a/src/includes/settings.h b/src/includes/settings.h
index 7eb5163..bb61b7e 100644
--- a/src/includes/settings.h
+++ b/src/includes/settings.h
@@ -1,17 +1,16 @@
 #define PREFIX "/cryptops/v0"
 #define PORT 8000
 #define ROOT_DEVICE "/dev/xvda"
-#define ROOT_SMALL_PARTITION_DEVICE ROOT_DEVICE "1"
-#define ROOT_BIG_PARTITION_DEVICE ROOT_DEVICE "2"
+#define INFO_PARTITION_DEVICE ROOT_DEVICE "1"
+#define DATA_PARTITION_DEVICE ROOT_DEVICE "2"
 #define MAPPED_DEVICE_NAME "xvda1_crypt"
 #define MAPPED_DEVICE_PATH "/dev/mapper/" MAPPED_DEVICE_NAME
 #define FILESYSTEM_TYPE "xfs"
 #define MEMORY_USAGE 0.9
 #define UNENCRYPTED_MOUNTPOINT "/tmp/mnt-plain"
-#define SMALL_MOUNTPOINT "/tmp/mnt-small"
-#define BIG_MOUNTPOINT "/tmp/mnt-big"
+#define INFO_MOUNTPOINT "/tmp/mnt-info"
+#define DATA_MOUNTPOINT "/tmp/mnt-data"
 #define TMP_LOCATION "/tmp/" MAPPED_DEVICE_NAME
 #define AUTHORIZED_KEYS_DIR "/root/.ssh"
 #define AUTHORIZED_KEYS_PATH AUTHORIZED_KEYS_DIR "/authorized_keys"
 #define SSH_HOST_KEY_DIR "/dropbear"
-#define SSH_HOST_KEY_PATH SSH_HOST_KEY_DIR "/dropbear_rsa_host_key"
-- 
GitLab