Message ID | 20190812175635.34186-5-ebiggers@kernel.org (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | xfsprogs: support fscrypt API additions in xfs_io | expand |
On 8/12/19 12:56 PM, Eric Biggers wrote: > From: Eric Biggers <ebiggers@google.com> > > get_encpolicy uses the FS_IOC_GET_ENCRYPTION_POLICY ioctl to retrieve > the file's encryption policy, then displays it. But that only works for > v1 encryption policies. A new ioctl, FS_IOC_GET_ENCRYPTION_POLICY_EX, > has been introduced which is more flexible and can retrieve both v1 and > v2 encryption policies. ... > +static void > +test_for_v2_policy_support(void) > +{ > + struct fscrypt_get_policy_ex_arg arg; > + > + arg.policy_size = sizeof(arg.policy); > + > + if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &arg) == 0 || > + errno == ENODATA /* file unencrypted */) { > + printf("supported\n"); > + return; > + } > + if (errno == ENOTTY) { > + printf("unsupported\n"); > + return; > + } > + fprintf(stderr, > + "%s: unexpected error checking for FS_IOC_GET_ENCRYPTION_POLICY_EX support: %s\n", Darrick also mentioned to me off-list that the io/encrypt.c code is chock full of strings that really need to be _("translatable") -Eric > + file->name, strerror(errno)); > + exitcode = 1; > +} > + > +static void > +show_v1_encryption_policy(const struct fscrypt_policy_v1 *policy) > +{ > + printf("Encryption policy for %s:\n", file->name); > + printf("\tPolicy version: %u\n", policy->version); > + printf("\tMaster key descriptor: %s\n", > + keydesc2str(policy->master_key_descriptor)); > + printf("\tContents encryption mode: %u (%s)\n", > + policy->contents_encryption_mode, > + mode2str(policy->contents_encryption_mode)); > + printf("\tFilenames encryption mode: %u (%s)\n", > + policy->filenames_encryption_mode, > + mode2str(policy->filenames_encryption_mode)); > + printf("\tFlags: 0x%02x\n", policy->flags); > +} > + > +static void > +show_v2_encryption_policy(const struct fscrypt_policy_v2 *policy) > +{ > + printf("Encryption policy for %s:\n", file->name); > + printf("\tPolicy version: %u\n", policy->version); > + printf("\tMaster key identifier: %s\n", > + keyid2str(policy->master_key_identifier)); > + printf("\tContents encryption mode: %u (%s)\n", > + policy->contents_encryption_mode, > + mode2str(policy->contents_encryption_mode)); > + printf("\tFilenames encryption mode: %u (%s)\n", > + policy->filenames_encryption_mode, > + mode2str(policy->filenames_encryption_mode)); > + printf("\tFlags: 0x%02x\n", policy->flags); > +} > + > static int > get_encpolicy_f(int argc, char **argv) > { > - struct fscrypt_policy policy; > + int c; > + struct fscrypt_get_policy_ex_arg arg; > + bool only_use_v1_ioctl = false; > + int res; > > - if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) < 0) { > + while ((c = getopt(argc, argv, "1t")) != EOF) { > + switch (c) { > + case '1': > + only_use_v1_ioctl = true; > + break; > + case 't': > + test_for_v2_policy_support(); > + return 0; > + default: > + return command_usage(&get_encpolicy_cmd); > + } > + } > + argc -= optind; > + argv += optind; > + > + if (argc != 0) > + return command_usage(&get_encpolicy_cmd); > + > + /* first try the new ioctl */ > + if (only_use_v1_ioctl) { > + res = -1; > + errno = ENOTTY; > + } else { > + arg.policy_size = sizeof(arg.policy); > + res = ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &arg); > + } > + > + /* fall back to the old ioctl */ > + if (res != 0 && errno == ENOTTY) > + res = ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY, > + &arg.policy.v1); > + > + if (res != 0) { > fprintf(stderr, "%s: failed to get encryption policy: %s\n", > file->name, strerror(errno)); > exitcode = 1; > return 0; > } > > - printf("Encryption policy for %s:\n", file->name); > - printf("\tPolicy version: %u\n", policy.version); > - printf("\tMaster key descriptor: %s\n", > - keydesc2str(policy.master_key_descriptor)); > - printf("\tContents encryption mode: %u (%s)\n", > - policy.contents_encryption_mode, > - mode2str(policy.contents_encryption_mode)); > - printf("\tFilenames encryption mode: %u (%s)\n", > - policy.filenames_encryption_mode, > - mode2str(policy.filenames_encryption_mode)); > - printf("\tFlags: 0x%02x\n", policy.flags); > + switch (arg.policy.version) { > + case FSCRYPT_POLICY_V1: > + show_v1_encryption_policy(&arg.policy.v1); > + break; > + case FSCRYPT_POLICY_V2: > + show_v2_encryption_policy(&arg.policy.v2); > + break; > + default: > + printf("Encryption policy for %s:\n", file->name); > + printf("\tPolicy version: %u (unknown)\n", arg.policy.version); > + break; > + } > return 0; > } > > @@ -351,11 +467,13 @@ encrypt_init(void) > { > get_encpolicy_cmd.name = "get_encpolicy"; > get_encpolicy_cmd.cfunc = get_encpolicy_f; > + get_encpolicy_cmd.args = _("[-1] [-t]"); > get_encpolicy_cmd.argmin = 0; > - get_encpolicy_cmd.argmax = 0; > + get_encpolicy_cmd.argmax = -1; > get_encpolicy_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; > get_encpolicy_cmd.oneline = > _("display the encryption policy of the current file"); > + get_encpolicy_cmd.help = get_encpolicy_help; > > set_encpolicy_cmd.name = "set_encpolicy"; > set_encpolicy_cmd.cfunc = set_encpolicy_f; > diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 > index 6e064bdd..3dd34a0c 100644 > --- a/man/man8/xfs_io.8 > +++ b/man/man8/xfs_io.8 > @@ -724,10 +724,21 @@ version of policy structure (numeric) > .RE > .PD > .TP > -.BR get_encpolicy > +.BI "get_encpolicy [ \-1 ] [ \-t ]" > On filesystems that support encryption, display the encryption policy of the > current file. > - > +.RS 1.0i > +.PD 0 > +.TP 0.4i > +.BI \-1 > +Use only the old ioctl to get the encryption policy. This only works if the > +file has a v1 encryption policy. > +.TP > +.BI \-t > +Test whether v2 encryption policies are supported. Prints "supported", > +"unsupported", or an error message. > +.RE > +.PD > .TP > .BR lsattr " [ " \-R " | " \-D " | " \-a " | " \-v " ]" > List extended inode flags on the currently open file. If the >
On Wed, Sep 25, 2019 at 12:23:25PM -0500, Eric Sandeen wrote: > On 8/12/19 12:56 PM, Eric Biggers wrote: > > From: Eric Biggers <ebiggers@google.com> > > > > get_encpolicy uses the FS_IOC_GET_ENCRYPTION_POLICY ioctl to retrieve > > the file's encryption policy, then displays it. But that only works for > > v1 encryption policies. A new ioctl, FS_IOC_GET_ENCRYPTION_POLICY_EX, > > has been introduced which is more flexible and can retrieve both v1 and > > v2 encryption policies. > > ... > > > +static void > > +test_for_v2_policy_support(void) > > +{ > > + struct fscrypt_get_policy_ex_arg arg; > > + > > + arg.policy_size = sizeof(arg.policy); > > + > > + if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &arg) == 0 || > > + errno == ENODATA /* file unencrypted */) { > > + printf("supported\n"); > > + return; > > + } > > + if (errno == ENOTTY) { > > + printf("unsupported\n"); > > + return; > > + } > > + fprintf(stderr, > > + "%s: unexpected error checking for FS_IOC_GET_ENCRYPTION_POLICY_EX support: %s\n", > > Darrick also mentioned to me off-list that the io/encrypt.c code is chock full of > strings that really need to be _("translatable") > Sure, I can do that, though is this really something that people want? These commands are only intended for testing, and the xfsprogs translations don't seem actively maintained (only 1 language was updated in the last 10 years?). - Eric
On 9/25/19 6:28 PM, Eric Biggers wrote: > On Wed, Sep 25, 2019 at 12:23:25PM -0500, Eric Sandeen wrote: >> On 8/12/19 12:56 PM, Eric Biggers wrote: >>> From: Eric Biggers <ebiggers@google.com> >>> >>> get_encpolicy uses the FS_IOC_GET_ENCRYPTION_POLICY ioctl to retrieve >>> the file's encryption policy, then displays it. But that only works for >>> v1 encryption policies. A new ioctl, FS_IOC_GET_ENCRYPTION_POLICY_EX, >>> has been introduced which is more flexible and can retrieve both v1 and >>> v2 encryption policies. >> >> ... >> ... >>> + fprintf(stderr, >>> + "%s: unexpected error checking for FS_IOC_GET_ENCRYPTION_POLICY_EX support: %s\n", >> >> Darrick also mentioned to me off-list that the io/encrypt.c code is chock full of >> strings that really need to be _("translatable") >> > > Sure, I can do that, though is this really something that people want? These > commands are only intended for testing, and the xfsprogs translations don't seem > actively maintained (only 1 language was updated in the last 10 years?). True that there's not a ton of translation going on now, but it's easy enough to toss in _("foo") and keep the possibility open, and be consistent. So thanks :) -Eric
diff --git a/io/encrypt.c b/io/encrypt.c index 11eb4a3e..5b92cfae 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2016 Google, Inc. All Rights Reserved. + * Copyright 2016, 2019 Google LLC * Author: Eric Biggers <ebiggers@google.com> */ @@ -139,6 +139,20 @@ struct fscrypt_get_key_status_arg { static cmdinfo_t get_encpolicy_cmd; static cmdinfo_t set_encpolicy_cmd; +static void +get_encpolicy_help(void) +{ + printf(_( +"\n" +" display the encryption policy of the current file\n" +"\n" +" -1 -- Use only the old ioctl to get the encryption policy.\n" +" This only works if the file has a v1 encryption policy.\n" +" -t -- Test whether v2 encryption policies are supported.\n" +" Prints \"supported\", \"unsupported\", or an error message.\n" +"\n")); +} + static void set_encpolicy_help(void) { @@ -218,7 +232,7 @@ mode2str(__u8 mode) } static const char * -keydesc2str(__u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]) +keydesc2str(const __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]) { static char buf[2 * FSCRYPT_KEY_DESCRIPTOR_SIZE + 1]; int i; @@ -229,29 +243,131 @@ keydesc2str(__u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]) return buf; } +static const char * +keyid2str(const __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) +{ + static char buf[2 * FSCRYPT_KEY_IDENTIFIER_SIZE + 1]; + int i; + + for (i = 0; i < FSCRYPT_KEY_IDENTIFIER_SIZE; i++) + sprintf(&buf[2 * i], "%02x", master_key_identifier[i]); + + return buf; +} + +static void +test_for_v2_policy_support(void) +{ + struct fscrypt_get_policy_ex_arg arg; + + arg.policy_size = sizeof(arg.policy); + + if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &arg) == 0 || + errno == ENODATA /* file unencrypted */) { + printf("supported\n"); + return; + } + if (errno == ENOTTY) { + printf("unsupported\n"); + return; + } + fprintf(stderr, + "%s: unexpected error checking for FS_IOC_GET_ENCRYPTION_POLICY_EX support: %s\n", + file->name, strerror(errno)); + exitcode = 1; +} + +static void +show_v1_encryption_policy(const struct fscrypt_policy_v1 *policy) +{ + printf("Encryption policy for %s:\n", file->name); + printf("\tPolicy version: %u\n", policy->version); + printf("\tMaster key descriptor: %s\n", + keydesc2str(policy->master_key_descriptor)); + printf("\tContents encryption mode: %u (%s)\n", + policy->contents_encryption_mode, + mode2str(policy->contents_encryption_mode)); + printf("\tFilenames encryption mode: %u (%s)\n", + policy->filenames_encryption_mode, + mode2str(policy->filenames_encryption_mode)); + printf("\tFlags: 0x%02x\n", policy->flags); +} + +static void +show_v2_encryption_policy(const struct fscrypt_policy_v2 *policy) +{ + printf("Encryption policy for %s:\n", file->name); + printf("\tPolicy version: %u\n", policy->version); + printf("\tMaster key identifier: %s\n", + keyid2str(policy->master_key_identifier)); + printf("\tContents encryption mode: %u (%s)\n", + policy->contents_encryption_mode, + mode2str(policy->contents_encryption_mode)); + printf("\tFilenames encryption mode: %u (%s)\n", + policy->filenames_encryption_mode, + mode2str(policy->filenames_encryption_mode)); + printf("\tFlags: 0x%02x\n", policy->flags); +} + static int get_encpolicy_f(int argc, char **argv) { - struct fscrypt_policy policy; + int c; + struct fscrypt_get_policy_ex_arg arg; + bool only_use_v1_ioctl = false; + int res; - if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) < 0) { + while ((c = getopt(argc, argv, "1t")) != EOF) { + switch (c) { + case '1': + only_use_v1_ioctl = true; + break; + case 't': + test_for_v2_policy_support(); + return 0; + default: + return command_usage(&get_encpolicy_cmd); + } + } + argc -= optind; + argv += optind; + + if (argc != 0) + return command_usage(&get_encpolicy_cmd); + + /* first try the new ioctl */ + if (only_use_v1_ioctl) { + res = -1; + errno = ENOTTY; + } else { + arg.policy_size = sizeof(arg.policy); + res = ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &arg); + } + + /* fall back to the old ioctl */ + if (res != 0 && errno == ENOTTY) + res = ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY, + &arg.policy.v1); + + if (res != 0) { fprintf(stderr, "%s: failed to get encryption policy: %s\n", file->name, strerror(errno)); exitcode = 1; return 0; } - printf("Encryption policy for %s:\n", file->name); - printf("\tPolicy version: %u\n", policy.version); - printf("\tMaster key descriptor: %s\n", - keydesc2str(policy.master_key_descriptor)); - printf("\tContents encryption mode: %u (%s)\n", - policy.contents_encryption_mode, - mode2str(policy.contents_encryption_mode)); - printf("\tFilenames encryption mode: %u (%s)\n", - policy.filenames_encryption_mode, - mode2str(policy.filenames_encryption_mode)); - printf("\tFlags: 0x%02x\n", policy.flags); + switch (arg.policy.version) { + case FSCRYPT_POLICY_V1: + show_v1_encryption_policy(&arg.policy.v1); + break; + case FSCRYPT_POLICY_V2: + show_v2_encryption_policy(&arg.policy.v2); + break; + default: + printf("Encryption policy for %s:\n", file->name); + printf("\tPolicy version: %u (unknown)\n", arg.policy.version); + break; + } return 0; } @@ -351,11 +467,13 @@ encrypt_init(void) { get_encpolicy_cmd.name = "get_encpolicy"; get_encpolicy_cmd.cfunc = get_encpolicy_f; + get_encpolicy_cmd.args = _("[-1] [-t]"); get_encpolicy_cmd.argmin = 0; - get_encpolicy_cmd.argmax = 0; + get_encpolicy_cmd.argmax = -1; get_encpolicy_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; get_encpolicy_cmd.oneline = _("display the encryption policy of the current file"); + get_encpolicy_cmd.help = get_encpolicy_help; set_encpolicy_cmd.name = "set_encpolicy"; set_encpolicy_cmd.cfunc = set_encpolicy_f; diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 6e064bdd..3dd34a0c 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -724,10 +724,21 @@ version of policy structure (numeric) .RE .PD .TP -.BR get_encpolicy +.BI "get_encpolicy [ \-1 ] [ \-t ]" On filesystems that support encryption, display the encryption policy of the current file. - +.RS 1.0i +.PD 0 +.TP 0.4i +.BI \-1 +Use only the old ioctl to get the encryption policy. This only works if the +file has a v1 encryption policy. +.TP +.BI \-t +Test whether v2 encryption policies are supported. Prints "supported", +"unsupported", or an error message. +.RE +.PD .TP .BR lsattr " [ " \-R " | " \-D " | " \-a " | " \-v " ]" List extended inode flags on the currently open file. If the