[systemd-devel] [PATCH] cryptsetup: craft a unique ID with the source device
Dimitri John Ledkov
dimitri.j.ledkov at intel.com
Fri May 29 07:45:11 PDT 2015
On 29 May 2015 at 11:17, <harald at redhat.com> wrote:
> 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.
>
I'm not sure why this is needed... if the device path is not good
enough, there is also luks UUID header. In Ubuntu we display the full
cryptsetup UUID in plymouth, but that's fairly cosmetic.
If the path is not good enough, maj/min are a bit pointless and you
really probably want the luks UUID then.
Regards,
Dimitri.
> 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
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
Regards,
Dimitri.
Pura Vida!
https://clearlinux.org
Open Source Technology Center
Intel Corporation (UK) Ltd. - Co. Reg. #1134945 - Pipers Way, Swindon SN3 1RJ.
More information about the systemd-devel
mailing list