[systemd-devel] [PATCH] cryptsetup: craft a unique ID with the source device
harald at redhat.com
harald at redhat.com
Fri May 29 03:17:12 PDT 2015
From: Harald Hoyer <harald at redhat.com>
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
More information about the systemd-devel
mailing list