From: Harald Hoyer <[email protected]> If cryptsetup is called with a source device as argv[3], then craft the ID for the password agent with a unique device path.
If possible "/dev/block/<maj>:<min>" is used, otherwise the original argv[3] is used. This enables password agents like petera [1] to provide a password according to the source device. The original ID did not carry enough information and was more targeted for a human readable string, which is specified in the "Message" field anyway. With this patch the ID of the ask.XXX ini file looks like this: ID=cryptsetup:/dev/block/<maj>:<min> [1] https://github.com/npmccallum/petera --- src/cryptsetup/cryptsetup.c | 97 ++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index a5018f1..130c36e 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -238,6 +238,33 @@ static void log_glue(int level, const char *msg, void *usrptr) { log_debug("%s", msg); } +static char* disk_maj_min(const char *path) { + struct stat st, st2; + char *i = NULL; + int r; + + assert(path); + + if (stat(path, &st) < 0) + return NULL; + + if (!S_ISBLK(st.st_mode)) + return NULL; + + asprintf(&i, "/dev/block/%d:%d", major(st.st_rdev), minor(st.st_rdev)); + + if (!i) + return strdup(path); + + r = stat(i, &st2); + if ((r < 0) || (st.st_rdev != st2.st_rdev)) { + free(i); + return strdup(path); + } + + return i; +} + static char* disk_description(const char *path) { static const char name_fields[] = @@ -295,20 +322,54 @@ static char *disk_mount_point(const char *label) { return NULL; } -static int get_password(const char *name, usec_t until, bool accept_cached, char ***passwords) { - int r; +static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***passwords) { + int r = 0; char **p; _cleanup_free_ char *text = NULL; _cleanup_free_ char *escaped_name = NULL; char *id; + const char *name = NULL; + _cleanup_free_ char *description = NULL, *name_buffer = NULL, + *mount_point = NULL, *maj_min = NULL; assert(name); assert(passwords); + description = disk_description(src); + mount_point = disk_mount_point(vol); + + if (description && streq(vol, description)) { + /* If the description string is simply the + * volume name, then let's not show this + * twice */ + free(description); + description = NULL; + } + + if (mount_point && description) + r = asprintf(&name_buffer, "%s (%s) on %s", description, vol, mount_point); + else if (mount_point) + r = asprintf(&name_buffer, "%s on %s", vol, mount_point); + else if (description) + r = asprintf(&name_buffer, "%s (%s)", description, vol); + + if (r < 0) { + log_oom(); + return r; + } + name = name_buffer ? name_buffer : vol; + if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) return log_oom(); - escaped_name = cescape(name); + if (src) + maj_min = disk_maj_min(src); + + if (maj_min) + escaped_name = maj_min; + else + escaped_name = cescape(name); + if (!escaped_name) return log_oom(); @@ -552,8 +613,7 @@ int main(int argc, char *argv[]) { unsigned tries; usec_t until; crypt_status_info status; - const char *key_file = NULL, *name = NULL; - _cleanup_free_ char *description = NULL, *name_buffer = NULL, *mount_point = NULL; + const char *key_file; /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */ @@ -581,31 +641,6 @@ int main(int argc, char *argv[]) { /* A delicious drop of snake oil */ mlockall(MCL_FUTURE); - description = disk_description(argv[3]); - mount_point = disk_mount_point(argv[2]); - - if (description && streq(argv[2], description)) { - /* If the description string is simply the - * volume name, then let's not show this - * twice */ - free(description); - description = NULL; - } - - k = 0; - if (mount_point && description) - k = asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point); - else if (mount_point) - k = asprintf(&name_buffer, "%s on %s", argv[2], mount_point); - else if (description) - k = asprintf(&name_buffer, "%s (%s)", description, argv[2]); - - if (k < 0) { - log_oom(); - goto finish; - } - name = name_buffer ? name_buffer : argv[2]; - if (arg_header) { log_debug("LUKS header: %s", arg_header); k = crypt_init(&cd, arg_header); @@ -652,7 +687,7 @@ int main(int argc, char *argv[]) { _cleanup_strv_free_ char **passwords = NULL; if (!key_file) { - k = get_password(name, until, tries == 0 && !arg_verify, &passwords); + k = get_password(argv[2], argv[3], until, tries == 0 && !arg_verify, &passwords); if (k == -EAGAIN) continue; else if (k < 0) -- 2.4.1 _______________________________________________ systemd-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/systemd-devel
