From 20c5c6f8349af0b05d388107e53957341f5205ed Mon Sep 17 00:00:00 2001
From: Arie Peterson <arie@greenhost.nl>
Date: Mon, 10 Jul 2017 10:18:27 +0200
Subject: [PATCH] Add endpoint for showing encryption status

---
 src/api/encryption.c       | 28 ++++++++++++++++++++++++++++
 src/api/encryption_init.c  |  4 +++-
 src/auxiliary.c            | 11 +++++++++++
 src/cryptops-api.c         |  4 ++++
 src/encryption_functions.c |  3 +--
 5 files changed, 47 insertions(+), 3 deletions(-)
 create mode 100644 src/api/encryption.c

diff --git a/src/api/encryption.c b/src/api/encryption.c
new file mode 100644
index 0000000..e576c3d
--- /dev/null
+++ b/src/api/encryption.c
@@ -0,0 +1,28 @@
+/**
+ * Callback function that shows the current encryption status (encrypted or
+ * unencrypted).
+ *
+ * Example output:
+ * {"encryption-status":"encrypted"}
+ *
+ * @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
+ * @return                internal status code
+ */
+int callback_encryption(const struct _u_request * request,
+    struct _u_response * response, void * user_data)
+{
+    char * encryption_status;
+    if (path_exists(DATA_PARTITION_DEVICE) &&
+        is_encrypted_device(DATA_PARTITION_DEVICE))
+    {
+        encryption_status = "encrypted";
+    }
+    else
+    {
+        encryption_status = "unencrypted";
+    }
+    return send_simple_response(response, 200,
+        "encryption-status", encryption_status);
+}
diff --git a/src/api/encryption_init.c b/src/api/encryption_init.c
index 17b1a0b..f708cd0 100644
--- a/src/api/encryption_init.c
+++ b/src/api/encryption_init.c
@@ -43,7 +43,9 @@ int callback_encryption_init(const struct _u_request * request,
     }
  
     // Check if the device isn't already encrypted.
-    if (is_encrypted_device(ROOT_DEVICE))
+    // Actually we check if the device has any partitions; if so, we're not in
+    // the expected situation of an unpartitioned unencrypted root device.
+    if (path_exists(INFO_PARTITION_DEVICE))
     {
         // The device is already encrypted; we don't want to encrypt it again.
         return send_simple_response(response, 500, "error",
diff --git a/src/auxiliary.c b/src/auxiliary.c
index 797839d..6b833d8 100644
--- a/src/auxiliary.c
+++ b/src/auxiliary.c
@@ -171,3 +171,14 @@ int parse_int(const char * input, int * result)
     *result = l;
     return 0;
 }
+
+/**
+ * Check if the given path already exists (as a (special) file or directory).
+ * @param  path  Path to test.
+ * @return       `true` if path exists, `false` otherwise.
+ */
+bool path_exists(const char * path)
+{
+    struct stat st = {0};
+    return (stat(path, &st) == 0);
+}
diff --git a/src/cryptops-api.c b/src/cryptops-api.c
index 5b1e102..5a49efd 100644
--- a/src/cryptops-api.c
+++ b/src/cryptops-api.c
@@ -6,6 +6,7 @@
 #include <auxiliary.c>
 #include <encryption_functions.c>
 #include <api/default.c>
+#include <api/encryption.c>
 #include <api/encryption_init.c>
 #include <api/encryption_unlock.c>
 #include <api/encryption_keys_put.c>
@@ -37,6 +38,9 @@ int main(int argc, char ** argv)
 
     // Add api endpoints.
     bool reboot = false;
+    ulfius_add_endpoint_by_val(&instance, "GET" , PREFIX,
+        "/encryption",
+        0, &callback_encryption, NULL);
     ulfius_add_endpoint_by_val(&instance, "POST", PREFIX,
         "/encryption/init",
         0, &callback_encryption_init, &reboot);
diff --git a/src/encryption_functions.c b/src/encryption_functions.c
index 1bc128a..9bbceec 100644
--- a/src/encryption_functions.c
+++ b/src/encryption_functions.c
@@ -11,8 +11,7 @@ static int container_initialise(struct crypt_device ** cd, const char * path,
     const bool debug)
 {
     // Check if the device exists.
-    struct stat st = {0};
-    if (stat(path, &st) == -1)
+    if (! path_exists(path))
     {
         printf("device does not exist: %s.\n", path);
         return 1;
-- 
GitLab