From c138264d35b7460b4a4370755517e194fe881eec Mon Sep 17 00:00:00 2001
From: Arie Peterson <arie@greenhost.nl>
Date: Thu, 20 Jul 2017 15:06:31 +0200
Subject: [PATCH] Merge encryption_keys_{post,put}

Replace the very similar encryption_keys_post and encryption_keys_put
callback functions by a single handler function, with a boolean flag to
separate the two variants.
---
 src/api/encryption_keys_post.c     |  69 ----------------
 src/api/encryption_keys_put.c      |  85 -------------------
 src/api/encryption_keys_put_post.c | 128 +++++++++++++++++++++++++++++
 src/cryptops-api.c                 |   3 +-
 4 files changed, 129 insertions(+), 156 deletions(-)
 delete mode 100644 src/api/encryption_keys_post.c
 delete mode 100644 src/api/encryption_keys_put.c
 create mode 100644 src/api/encryption_keys_put_post.c

diff --git a/src/api/encryption_keys_post.c b/src/api/encryption_keys_post.c
deleted file mode 100644
index 878f90b..0000000
--- a/src/api/encryption_keys_post.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * Callback function to add a luks encryption password.
- * @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_keys_post(const struct _u_request * request,
-    struct _u_response * response, void * user_data)
-{
-    int r;
-
-    // Read in json request body.
-    json_t * json_input = ulfius_get_json_body_request(request, NULL);
-
-    // Read (current) password from request.
-    const char * password;
-    password = json_string_value(json_object_get(json_input, "password"));
-    if (password == NULL)
-    {
-        return send_simple_response(response, 400, "error", "missing password");
-    }
-
-    // Read new password from request.
-    const char * new_password;
-    new_password = json_string_value(json_object_get(json_input,
-        "new-password"));
-    if (new_password == NULL)
-    {
-        return send_simple_response(response, 400, "error",
-            "missing new password");
-    }
-
-    // Initialise encrypted container.
-    struct crypt_device * cd = NULL;
-    r = container_initialise(&cd, DATA_PARTITION_DEVICE, true);
-    if (r < 0)
-    {
-        crypt_free(cd);
-    }
-    if (r != 0)
-    {
-        printf("container_initialise failed with status %d\n", r);
-        return send_simple_response(response, 500, "error",
-            "initialising encrypted container failed");
-    }
-
-    // Add encryption password.
-    r = crypt_keyslot_add_by_passphrase(cd, CRYPT_ANY_SLOT,
-        password, strlen(password), new_password, strlen(new_password));
-  
-    if (r == -1)
-    {
-        // Experience learns that -1 is returned when the password is wrong.
-        return send_simple_response(response, 403, "error",
-           "incorrect password");
-    }
-  
-    if (r < 0)
-    {
-        // Something else went wrong.
-        printf("crypt_keyslot_add_by_passphrase failed with status %d\n", r);
-        return send_simple_response(response, 500, "error",
-            "error changing password");
-    }
-  
-    // If we reach this point, apparently everything went well.
-    return send_simple_response(response, 200, "status", "ok");
-}
diff --git a/src/api/encryption_keys_put.c b/src/api/encryption_keys_put.c
deleted file mode 100644
index 4555225..0000000
--- a/src/api/encryption_keys_put.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * Callback function to change a luks encryption password.
- * @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_keys_put(const struct _u_request * request,
-    struct _u_response * response, void * user_data)
-{
-    int r;
-
-    // Read in json request body.
-    json_t * json_input = ulfius_get_json_body_request(request, NULL);
-
-    // Read (current) password from request.
-    const char * password;
-    password = json_string_value(json_object_get(json_input, "password"));
-    if (password == NULL)
-    {
-        return send_simple_response(response, 400, "error", "missing password");
-    }
-
-    // Read new password from request.
-    const char * new_password;
-    new_password = json_string_value(json_object_get(json_input,
-        "new-password"));
-    if (new_password == NULL)
-    {
-        return send_simple_response(response, 400, "error",
-            "missing new password");
-    }
-
-    // Read keyslot from request URI.
-    const char * keyslot_string = u_map_get(request->map_url, "slot");
-    if (keyslot_string == NULL)
-    {
-        return send_simple_response(response, 400, "error",
-            "missing url parameter `slot`");
-    }
-    int keyslot;
-    r = parse_int(keyslot_string, &keyslot);
-    if (r != 0)
-    {
-        printf("invalid url parameter `slot`: %s\n", keyslot_string);
-        return send_simple_response(response, 400, "error",
-            "invalid url parameter `slot`");
-    }
-
-    // Initialise encrypted container.
-    struct crypt_device * cd = NULL;
-    r = container_initialise(&cd, DATA_PARTITION_DEVICE, true);
-    if (r < 0)
-    {
-        crypt_free(cd);
-    }
-    if (r != 0)
-    {
-        printf("container_initialise failed with status %d\n", r);
-        return send_simple_response(response, 500, "error",
-            "initialising encrypted container failed");
-    }
-
-    // Add encryption password.
-    r = crypt_keyslot_change_by_passphrase(cd, keyslot, keyslot,
-        password, strlen(password), new_password, strlen(new_password));
-  
-    if (r == -1)
-    {
-        // Experience learns that -1 is returned when the password is wrong.
-        return send_simple_response(response, 403, "error",
-           "incorrect password");
-    }
-  
-    if (r < 0)
-    {
-        // Something else went wrong.
-        printf("crypt_keyslot_change_by_passphrase failed with status %d\n", r);
-        return send_simple_response(response, 500, "error",
-            "error changing password");
-    }
-  
-    // If we reach this point, apparently everything went well.
-    return send_simple_response(response, 200, "status", "ok");
-}
diff --git a/src/api/encryption_keys_put_post.c b/src/api/encryption_keys_put_post.c
new file mode 100644
index 0000000..867b3a6
--- /dev/null
+++ b/src/api/encryption_keys_put_post.c
@@ -0,0 +1,128 @@
+/**
+ * Combined handler for adding and changing luks encryption passwords.
+ * @param[in]   request   incoming HTTP request
+ * @param[out]  response  HTTP response to the request
+ * @param[in]   is_post   this is a post request (true) or a put (false)
+ * @return                internal status code
+ */
+int encryption_keys_change(const struct _u_request * request,
+    struct _u_response * response, bool is_post)
+{
+    int r;
+
+    // Read in json request body.
+    json_t * json_input = ulfius_get_json_body_request(request, NULL);
+
+    // Read (current) password from request.
+    const char * password;
+    password = json_string_value(json_object_get(json_input, "password"));
+    if (password == NULL)
+    {
+        return send_simple_response(response, 400, "error", "missing password");
+    }
+
+    // Read new password from request.
+    const char * new_password;
+    new_password = json_string_value(json_object_get(json_input,
+        "new-password"));
+    if (new_password == NULL)
+    {
+        return send_simple_response(response, 400, "error",
+            "missing new password");
+    }
+
+    int keyslot;
+    // Posting a new password, put it in the first available slot.
+    if (is_post)
+    {
+        keyslot = CRYPT_ANY_SLOT;
+    }
+    // Changing an existing password, so read the slot from the url.
+    else
+    {
+        // Read keyslot from request URI.
+        const char * keyslot_string = u_map_get(request->map_url, "slot");
+        if (keyslot_string == NULL)
+        {
+            return send_simple_response(response, 400, "error",
+                "missing url parameter `slot`");
+        }
+        r = parse_int(keyslot_string, &keyslot);
+        if (r != 0)
+        {
+            printf("invalid url parameter `slot`: %s\n", keyslot_string);
+            return send_simple_response(response, 400, "error",
+                "invalid url parameter `slot`");
+        }
+    }
+
+    // Initialise encrypted container.
+    struct crypt_device * cd = NULL;
+    r = container_initialise(&cd, DATA_PARTITION_DEVICE, true);
+    if (r < 0)
+    {
+        crypt_free(cd);
+    }
+    if (r != 0)
+    {
+        printf("container_initialise failed with status %d\n", r);
+        return send_simple_response(response, 500, "error",
+            "initialising encrypted container failed");
+    }
+
+    if (is_post)
+    {
+        // Add encryption password.
+        r = crypt_keyslot_add_by_passphrase(cd, keyslot,
+            password, strlen(password), new_password, strlen(new_password));
+    }
+    else
+    {
+        // Change encryption password.
+        r = crypt_keyslot_change_by_passphrase(cd, keyslot, keyslot,
+            password, strlen(password), new_password, strlen(new_password));
+    }
+  
+    if (r == -1)
+    {
+        // Experience learns that -1 is returned when the password is wrong.
+        return send_simple_response(response, 403, "error",
+           "incorrect password");
+    }
+  
+    if (r < 0)
+    {
+        // Something else went wrong.
+        printf("crypt_keyslot_add_by_passphrase failed with status %d\n", r);
+        return send_simple_response(response, 500, "error",
+            "error changing password");
+    }
+  
+    // If we reach this point, apparently everything went well.
+    return send_simple_response(response, 200, "status", "ok");
+}
+
+/**
+ * Callback function to add a luks encryption password.
+ * @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_keys_post(const struct _u_request * request,
+    struct _u_response * response, void * user_data)
+{
+    return encryption_keys_change(request, response, true);
+}
+/**
+ * Callback function to change a luks encryption password.
+ * @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_keys_put(const struct _u_request * request,
+    struct _u_response * response, void * user_data)
+{
+    return encryption_keys_change(request, response, false);
+}
diff --git a/src/cryptops-api.c b/src/cryptops-api.c
index 9944624..c630a51 100644
--- a/src/cryptops-api.c
+++ b/src/cryptops-api.c
@@ -11,8 +11,7 @@
 #include <api/encryption_remove_post.c>
 #include <api/encryption_unlock_post.c>
 #include <api/encryption_keys_get.c>
-#include <api/encryption_keys_post.c>
-#include <api/encryption_keys_put.c>
+#include <api/encryption_keys_put_post.c>
 #include <api/ssh_keys_get.c>
 #include <api/ssh_keys_put.c>
 #include <api/ssh_keys_post.c>
-- 
GitLab