storage: Factor encryption out of filesystem type when formatting

This way, people can easily make encrypted block devices without
filesystems in them.

Fixes #11482
Closes #11712
This commit is contained in:
Marius Vollmer 2019-04-30 12:40:23 +03:00 committed by Martin Pitt
parent d2a67e544b
commit e29dde4e94
5 changed files with 83 additions and 56 deletions

View File

@ -106,25 +106,30 @@ export function mounting_dialog_options(vals) {
return unparse_options(opts);
}
export function crypto_options_dialog_fields(options, visible) {
export function crypto_options_dialog_fields(options, visible, include_store_passphrase) {
var split_options = parse_options(options);
var opt_auto = !extract_option(split_options, "noauto");
var opt_ro = extract_option(split_options, "readonly");
var extra_options = unparse_options(split_options);
var fields = [
{ title: _("Unlock at boot"), tag: "auto" },
{ title: _("Unlock read only"), tag: "ro" },
{ title: _("Custom encryption options"), tag: "extra", type: "checkboxWithInput" },
];
if (include_store_passphrase)
fields = [ { title: _("Store passphrase"), tag: "store_passphrase" } ].concat(fields);
return [
CheckBoxes("crypto_options", _("Encryption Options"),
CheckBoxes("crypto_options", "",
{ visible: visible,
value: {
auto: opt_auto,
ro: opt_ro,
extra: extra_options === "" ? false : extra_options
},
fields: [
{ title: _("Unlock at boot"), tag: "auto" },
{ title: _("Unlock read only"), tag: "ro" },
{ title: _("Custom encryption options"), tag: "extra", type: "checkboxWithInput" },
]
fields: fields
},
),
];
@ -180,14 +185,14 @@ export function format_dialog(client, path, start, size, enable_dos_extended) {
else
title = cockpit.format(_("Format $0"), utils.block_name(block));
function is_encrypted(vals) {
return vals.type == "luks+xfs" || vals.type == "luks+ext4";
}
function is_filesystem(vals) {
return vals.type != "empty" && vals.type != "dos-extended";
}
function is_encrypted(vals) {
return vals.crypto.on;
}
/* Older UDisks2 implementation don't have good
* enough support for maintaining fstab and crypptab, so
* we don't offer that in the UI. (Most importantly, they
@ -242,8 +247,6 @@ export function format_dialog(client, path, start, size, enable_dos_extended) {
var filesystem_options = [ ];
add_fsys("xfs", { value: "xfs", title: "XFS - " + _("Recommended default") });
add_fsys("ext4", { value: "ext4", title: "EXT4" });
add_fsys("xfs", { value: "luks+xfs", title: _("Encrypted XFS (LUKS)") });
add_fsys("ext4", { value: "luks+ext4", title: _("Encrypted EXT4 (LUKS)") });
add_fsys("vfat", { value: "vfat", title: "VFAT" });
add_fsys("ntfs", { value: "ntfs", title: "NTFS" });
add_fsys(true, { value: "empty", title: _("No Filesystem") });
@ -284,29 +287,28 @@ export function format_dialog(client, path, start, size, enable_dos_extended) {
{ validate: (name, vals) => utils.validate_fsys_label(name, vals.type),
visible: is_filesystem
}),
PassInput("passphrase", _("Passphrase"),
{ validate: function (phrase) {
if (phrase === "")
return _("Passphrase cannot be empty");
},
visible: is_encrypted
}),
PassInput("passphrase2", _("Confirm passphrase"),
{ validate: function (phrase2, vals) {
if (phrase2 != vals.passphrase)
return _("Passphrases do not match");
},
visible: is_encrypted
}),
CheckBoxes("store_passphrase", "",
{
fields: [
{ tag: "val", title: _("Store passphrase") }
],
visible: is_encrypted_and_not_old_udisks2
})
].concat(crypto_options_dialog_fields(crypto_options, is_encrypted_and_not_old_udisks2))
.concat(mounting_dialog_fields(false, "", mount_options, is_filesystem_and_not_old_udisks2)),
CheckBoxes("crypto", "",
{ fields: [
{ tag: "on", title: _("Encrypt data") }
]
}),
[
PassInput("passphrase", _("Passphrase"),
{ validate: function (phrase) {
if (phrase === "")
return _("Passphrase cannot be empty");
},
visible: is_encrypted
}),
PassInput("passphrase2", _("Confirm"),
{ validate: function (phrase2, vals) {
if (phrase2 != vals.passphrase)
return _("Passphrases do not match");
},
visible: is_encrypted
})
].concat(crypto_options_dialog_fields(crypto_options, is_encrypted_and_not_old_udisks2, true))
].concat(mounting_dialog_fields(false, "", mount_options, is_filesystem_and_not_old_udisks2)),
update: function (dlg, vals, trigger) {
if (trigger == "crypto_options" && vals.crypto_options.auto == false)
dlg.set_nested_values("mount_options", { auto: false });
@ -349,16 +351,14 @@ export function format_dialog(client, path, start, size, enable_dos_extended) {
"track-parents": { t: 'b', v: true }
}]);
var crypto_options = crypto_options_dialog_options(vals);
if (is_encrypted(vals)) {
vals.type = vals.type.replace("luks+", "");
options["encrypt.passphrase"] = { t: 's', v: vals.passphrase };
var item = {
options: { t: 'ay', v: utils.encode_filename(crypto_options) },
options: { t: 'ay', v: utils.encode_filename(crypto_options_dialog_options(vals)) },
"track-parents": { t: 'b', v: true }
};
if (vals.store_passphrase && vals.store_passphrase.val) {
if (vals.crypto_options && vals.crypto_options.store_passphrase) {
item["passphrase-contents"] =
{ t: 'ay', v: utils.encode_filename(vals.passphrase) };
} else {

View File

@ -59,7 +59,8 @@ class TestStorage(StorageCase):
self.content_row_wait_in_col(1, 2, "/dev/TEST/lvol")
self.content_head_action(1, "Format")
self.dialog({"type": "luks+ext4",
self.dialog({"type": "ext4",
"crypto.on": True,
"name": "FS",
"passphrase": "einszweidrei",
"passphrase2": "einszweidrei",

View File

@ -49,15 +49,16 @@ class TestStorage(StorageCase):
self.content_row_action(1, "Create Partition")
self.dialog_wait_open()
self.dialog_set_val("size", 17)
self.dialog_set_val("type", "luks+ext4")
self.dialog_set_val("type", "ext4")
self.dialog_set_val("crypto.on", True)
self.dialog_set_val("name", "ENCRYPTED")
self.dialog_set_val("passphrase", "vainu-reku-toma-rolle-kaja")
self.dialog_set_val("passphrase2", "vainu-reku-toma-rolle-kaja")
if not self.storaged_is_old_udisks:
self.dialog_set_val("store_passphrase.val", True)
self.dialog_set_val("crypto_options.store_passphrase", True)
self.dialog_set_val("crypto_options.extra", "crypto,options")
self.dialog_set_val("mounting", "custom")
self.dialog_set_val("mount_point", mount_point_secret)
self.dialog_set_val("crypto_options.extra", "crypto,options")
self.dialog_apply()
self.dialog_wait_close()
self.content_row_wait_in_col(1, 1, "Encrypted data")
@ -168,7 +169,8 @@ class TestStorage(StorageCase):
b.wait_visible("#storage-detail")
self.content_head_action(1, "Format")
self.dialog({"type": "luks+ext4",
self.dialog({"type": "ext4",
"crypto.on": True,
"name": "ENCRYPTED",
"passphrase": "vainu-reku-toma-rolle-kaja",
"passphrase2": "vainu-reku-toma-rolle-kaja"})
@ -246,7 +248,8 @@ class TestStorage(StorageCase):
b.wait_visible("#storage-detail")
# create volume and passphrase
self.content_head_action(1, "Format")
self.dialog({"type": "luks+ext4",
self.dialog({"type": "ext4",
"crypto.on": True,
"name": "ENCRYPTED",
"passphrase": "vainu-reku-toma-rolle-kaja",
"passphrase2": "vainu-reku-toma-rolle-kaja"})
@ -353,5 +356,25 @@ class TestStorage(StorageCase):
self.content_row_wait_in_col(2, 1, "ext4 File System")
def testNoFsys(self):
m = self.machine
b = self.browser
self.login_and_go("/storage")
# Add a disk and format it with luks, but without filesystem
m.add_disk("50M", serial="MYDISK")
b.wait_in_text("#drives", "MYDISK")
b.click('tr:contains("MYDISK")')
b.wait_visible("#storage-detail")
self.content_head_action(1, "Format")
self.dialog({"type": "empty",
"crypto.on": True,
"passphrase": "vainu-reku-toma-rolle-kaja",
"passphrase2": "vainu-reku-toma-rolle-kaja"})
self.content_row_wait_in_col(1, 1, "Encrypted data")
self.content_row_wait_in_col(2, 1, "Unrecognized Data")
if __name__ == '__main__':
test_main()

View File

@ -165,7 +165,8 @@ class TestStorage(StorageCase):
self.content_head_action(1, "Format")
self.dialog_wait_open()
self.dialog_set_val("type", "luks+ext4")
self.dialog_set_val("type", "ext4")
self.dialog_set_val("crypto.on", True)
self.dialog_set_val("mounting", "custom")
def wait_checked(field):

View File

@ -29,12 +29,12 @@ from testlib import *
@skipImage("UDisks doesn't have support for LVM", "debian-stable")
class TestStorage(StorageCase):
def checkResize(self, fsys, can_shrink, can_grow, shrink_needs_unmount=None, grow_needs_unmount=None,
def checkResize(self, fsys, crypto, can_shrink, can_grow, shrink_needs_unmount=None, grow_needs_unmount=None,
need_passphrase=False):
m = self.machine
b = self.browser
if fsys.startswith("luks+"):
if crypto:
fsys_row = 2
fsys_tab = 1
else:
@ -57,7 +57,8 @@ class TestStorage(StorageCase):
self.dialog_wait_apply_enabled()
self.dialog_set_val("name", "FSYS")
self.dialog_set_val("type", fsys)
if fsys.startswith("luks+"):
if crypto:
self.dialog_set_val("crypto.on", crypto)
self.dialog_set_val("passphrase", "vainu-reku-toma-rolle-kaja")
self.dialog_set_val("passphrase2", "vainu-reku-toma-rolle-kaja")
self.dialog_apply()
@ -113,18 +114,18 @@ class TestStorage(StorageCase):
self.wait_content_tab_action_disabled(1, 1, "Shrink")
def testResizeExt4(self):
self.checkResize("ext4",
self.checkResize("ext4", False,
can_shrink=True, shrink_needs_unmount=True,
can_grow=True, grow_needs_unmount=False)
def testResizeXfs(self):
self.checkResize("xfs",
self.checkResize("xfs", False,
can_shrink=False,
can_grow=True, grow_needs_unmount=False)
@skipImage("No NTFS support installed", "centos-7", "rhel-7-6", "rhel-7-6-distropkg", "rhel-7-7", "rhel-8-0", "rhel-8-0-distropkg", "rhel-8-1")
def testResizeNtfs(self):
self.checkResize("ntfs",
self.checkResize("ntfs", None,
can_shrink=True, shrink_needs_unmount=True,
can_grow=True, grow_needs_unmount=True)
@ -132,12 +133,12 @@ class TestStorage(StorageCase):
# Only newer versions of UDisks support resizing encrypted block devices
if self.machine.image in ["rhel-7-6", "rhel-7-6-distropkg", "rhel-7-7", "rhel-8-0", "rhel-8-0-distropkg", "rhel-8-1", "fedora-29",
"fedora-30", "fedora-testing", "fedora-i386", "debian-testing", "ubuntu-stable", "centos-7"]:
self.checkResize("luks+ext4",
self.checkResize("ext4", True,
can_shrink=True, shrink_needs_unmount=True,
can_grow=True, grow_needs_unmount=False,
need_passphrase=(self.machine.image in ["rhel-8-0", "rhel-8-0-distropkg", "rhel-8-1"]))
else:
self.checkResize("luks+ext4",
self.checkResize("ext4", True,
can_shrink=False,
can_grow=False)
@ -245,7 +246,8 @@ class TestStorage(StorageCase):
self.content_head_action(1, "Format")
self.dialog_wait_open()
self.dialog_set_val("name", "FSYS")
self.dialog_set_val("type", "luks+ext4")
self.dialog_set_val("type", "ext4")
self.dialog_set_val("crypto.on", True)
self.dialog_set_val("passphrase", "vainu-reku-toma-rolle-kaja")
self.dialog_set_val("passphrase2", "vainu-reku-toma-rolle-kaja")
self.dialog_apply()