Zbigniew Jędrzejewski-Szmek 436654
From 3357627f3380e680cbaaaddb9ecf4cd2872d46dd Mon Sep 17 00:00:00 2001
Harald Hoyer 4dc6b4
From: Harald Hoyer <harald@redhat.com>
Harald Hoyer 4dc6b4
Date: Mon, 1 Jun 2015 17:26:27 +0200
Zbigniew Jędrzejewski-Szmek 436654
Subject: [PATCH] cryptsetup: craft a unique ID with the source device
Harald Hoyer 4dc6b4
Harald Hoyer 4dc6b4
If cryptsetup is called with a source device as argv[3], then craft the
Harald Hoyer 4dc6b4
ID for the password agent with a unique device path.
Harald Hoyer 4dc6b4
Harald Hoyer 4dc6b4
If possible "/dev/block/<maj>:<min>" is used, otherwise the original
Harald Hoyer 4dc6b4
argv[3] is used.
Harald Hoyer 4dc6b4
Harald Hoyer 4dc6b4
This enables password agents like petera [1] to provide a password
Harald Hoyer 4dc6b4
according to the source device. The original ID did not carry enough
Harald Hoyer 4dc6b4
information and was more targeted for a human readable string, which
Harald Hoyer 4dc6b4
is specified in the "Message" field anyway.
Harald Hoyer 4dc6b4
Harald Hoyer 4dc6b4
With this patch the ID of the ask.XXX ini file looks like this:
Harald Hoyer 4dc6b4
ID=cryptsetup:/dev/block/<maj>:<min>
Harald Hoyer 4dc6b4
Harald Hoyer 4dc6b4
[1] https://github.com/npmccallum/petera
Zbigniew Jędrzejewski-Szmek 436654
Zbigniew Jędrzejewski-Szmek 436654
(cherry picked from commit e51b9486d1b59e72c293028fed1384f4e4ef09aa)
Harald Hoyer 4dc6b4
---
Harald Hoyer 4dc6b4
 src/cryptsetup/cryptsetup.c | 90 +++++++++++++++++++++++++++++----------------
Harald Hoyer 4dc6b4
 1 file changed, 58 insertions(+), 32 deletions(-)
Harald Hoyer 4dc6b4
Harald Hoyer 4dc6b4
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
Zbigniew Jędrzejewski-Szmek 436654
index a5018f13ed..5c6c7c0ed8 100644
Harald Hoyer 4dc6b4
--- a/src/cryptsetup/cryptsetup.c
Harald Hoyer 4dc6b4
+++ b/src/cryptsetup/cryptsetup.c
Harald Hoyer 4dc6b4
@@ -238,6 +238,23 @@ static void log_glue(int level, const char *msg, void *usrptr) {
Harald Hoyer 4dc6b4
         log_debug("%s", msg);
Harald Hoyer 4dc6b4
 }
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
+static int disk_major_minor(const char *path, char **ret) {
Harald Hoyer 4dc6b4
+        struct stat st;
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
+        assert(path);
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
+        if (stat(path, &st) < 0)
Harald Hoyer 4dc6b4
+                return -errno;
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
+        if (!S_ISBLK(st.st_mode))
Harald Hoyer 4dc6b4
+                return -EINVAL;
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
+        if (asprintf(ret, "/dev/block/%d:%d", major(st.st_rdev), minor(st.st_rdev)) < 0)
Harald Hoyer 4dc6b4
+                return -errno;
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
+        return 0;
Harald Hoyer 4dc6b4
+}
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
 static char* disk_description(const char *path) {
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
         static const char name_fields[] =
Harald Hoyer 4dc6b4
@@ -295,20 +312,55 @@ static char *disk_mount_point(const char *label) {
Harald Hoyer 4dc6b4
         return NULL;
Harald Hoyer 4dc6b4
 }
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
-static int get_password(const char *name, usec_t until, bool accept_cached, char ***passwords) {
Harald Hoyer 4dc6b4
-        int r;
Harald Hoyer 4dc6b4
+static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***passwords) {
Harald Hoyer 4dc6b4
+        int r = 0;
Harald Hoyer 4dc6b4
         char **p;
Harald Hoyer 4dc6b4
         _cleanup_free_ char *text = NULL;
Harald Hoyer 4dc6b4
         _cleanup_free_ char *escaped_name = NULL;
Harald Hoyer 4dc6b4
         char *id;
Harald Hoyer 4dc6b4
+        const char *name = NULL;
Harald Hoyer 4dc6b4
+        _cleanup_free_ char *description = NULL, *name_buffer = NULL,
Harald Hoyer 4dc6b4
+                *mount_point = NULL, *maj_min = NULL;
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
-        assert(name);
Harald Hoyer 4dc6b4
+        assert(vol);
Harald Hoyer 4dc6b4
+        assert(src);
Harald Hoyer 4dc6b4
         assert(passwords);
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
+        description = disk_description(src);
Harald Hoyer 4dc6b4
+        mount_point = disk_mount_point(vol);
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
+        if (description && streq(vol, description)) {
Harald Hoyer 4dc6b4
+                /* If the description string is simply the
Harald Hoyer 4dc6b4
+                 * volume name, then let's not show this
Harald Hoyer 4dc6b4
+                 * twice */
Harald Hoyer 4dc6b4
+                free(description);
Harald Hoyer 4dc6b4
+                description = NULL;
Harald Hoyer 4dc6b4
+        }
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
+        if (mount_point && description)
Harald Hoyer 4dc6b4
+                r = asprintf(&name_buffer, "%s (%s) on %s", description, vol, mount_point);
Harald Hoyer 4dc6b4
+        else if (mount_point)
Harald Hoyer 4dc6b4
+                r = asprintf(&name_buffer, "%s on %s", vol, mount_point);
Harald Hoyer 4dc6b4
+        else if (description)
Harald Hoyer 4dc6b4
+                r = asprintf(&name_buffer, "%s (%s)", description, vol);
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
+        if (r < 0)
Harald Hoyer 4dc6b4
+                return log_oom();
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
+        name = name_buffer ? name_buffer : vol;
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
         if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0)
Harald Hoyer 4dc6b4
                 return log_oom();
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
-        escaped_name = cescape(name);
Harald Hoyer 4dc6b4
+        if (src)
Harald Hoyer 4dc6b4
+                (void) disk_major_minor(src, &maj_min);
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
+        if (maj_min) {
Harald Hoyer 4dc6b4
+                escaped_name = maj_min;
Harald Hoyer 4dc6b4
+                maj_min = NULL;
Harald Hoyer 4dc6b4
+        } else
Harald Hoyer 4dc6b4
+                escaped_name = cescape(name);
Harald Hoyer 4dc6b4
+
Harald Hoyer 4dc6b4
         if (!escaped_name)
Harald Hoyer 4dc6b4
                 return log_oom();
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
@@ -552,8 +604,7 @@ int main(int argc, char *argv[]) {
Harald Hoyer 4dc6b4
                 unsigned tries;
Harald Hoyer 4dc6b4
                 usec_t until;
Harald Hoyer 4dc6b4
                 crypt_status_info status;
Harald Hoyer 4dc6b4
-                const char *key_file = NULL, *name = NULL;
Harald Hoyer 4dc6b4
-                _cleanup_free_ char *description = NULL, *name_buffer = NULL, *mount_point = NULL;
Harald Hoyer 4dc6b4
+                const char *key_file = NULL;
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
                 /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
@@ -581,31 +632,6 @@ int main(int argc, char *argv[]) {
Harald Hoyer 4dc6b4
                 /* A delicious drop of snake oil */
Harald Hoyer 4dc6b4
                 mlockall(MCL_FUTURE);
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
-                description = disk_description(argv[3]);
Harald Hoyer 4dc6b4
-                mount_point = disk_mount_point(argv[2]);
Harald Hoyer 4dc6b4
-
Harald Hoyer 4dc6b4
-                if (description && streq(argv[2], description)) {
Harald Hoyer 4dc6b4
-                        /* If the description string is simply the
Harald Hoyer 4dc6b4
-                         * volume name, then let's not show this
Harald Hoyer 4dc6b4
-                         * twice */
Harald Hoyer 4dc6b4
-                        free(description);
Harald Hoyer 4dc6b4
-                        description = NULL;
Harald Hoyer 4dc6b4
-                }
Harald Hoyer 4dc6b4
-
Harald Hoyer 4dc6b4
-                k = 0;
Harald Hoyer 4dc6b4
-                if (mount_point && description)
Harald Hoyer 4dc6b4
-                        k = asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point);
Harald Hoyer 4dc6b4
-                else if (mount_point)
Harald Hoyer 4dc6b4
-                        k = asprintf(&name_buffer, "%s on %s", argv[2], mount_point);
Harald Hoyer 4dc6b4
-                else if (description)
Harald Hoyer 4dc6b4
-                        k = asprintf(&name_buffer, "%s (%s)", description, argv[2]);
Harald Hoyer 4dc6b4
-
Harald Hoyer 4dc6b4
-                if (k < 0) {
Harald Hoyer 4dc6b4
-                        log_oom();
Harald Hoyer 4dc6b4
-                        goto finish;
Harald Hoyer 4dc6b4
-                }
Harald Hoyer 4dc6b4
-                name = name_buffer ? name_buffer : argv[2];
Harald Hoyer 4dc6b4
-
Harald Hoyer 4dc6b4
                 if (arg_header) {
Harald Hoyer 4dc6b4
                         log_debug("LUKS header: %s", arg_header);
Harald Hoyer 4dc6b4
                         k = crypt_init(&cd, arg_header);
Harald Hoyer 4dc6b4
@@ -652,7 +678,7 @@ int main(int argc, char *argv[]) {
Harald Hoyer 4dc6b4
                         _cleanup_strv_free_ char **passwords = NULL;
Harald Hoyer 4dc6b4
 
Harald Hoyer 4dc6b4
                         if (!key_file) {
Harald Hoyer 4dc6b4
-                                k = get_password(name, until, tries == 0 && !arg_verify, &passwords);
Harald Hoyer 4dc6b4
+                                k = get_password(argv[2], argv[3], until, tries == 0 && !arg_verify, &passwords);
Harald Hoyer 4dc6b4
                                 if (k == -EAGAIN)
Harald Hoyer 4dc6b4
                                         continue;
Harald Hoyer 4dc6b4
                                 else if (k < 0)