Skip to content

Commit

Permalink
storage: Tang keyserver and passphrase management for Stratis
Browse files Browse the repository at this point in the history
  • Loading branch information
mvollmer committed May 29, 2023
1 parent df135e7 commit eadabc0
Show file tree
Hide file tree
Showing 6 changed files with 506 additions and 72 deletions.
32 changes: 19 additions & 13 deletions pkg/storaged/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -970,11 +970,11 @@ function stratis3_start() {
return client.stratis_manager.StartPool(uuid, [!!unlock_method, unlock_method || ""]);
};

client.stratis_create_pool = (name, devs, key_desc) => {
client.stratis_create_pool = (name, devs, key_desc, clevis_info) => {
return client.stratis_manager.CreatePool(name, [false, 0],
devs,
key_desc ? [true, key_desc] : [false, ""],
[false, ["", ""]]);
clevis_info ? [true, clevis_info] : [false, ["", ""]]);
};

client.stratis_list_keys = () => {
Expand Down Expand Up @@ -1056,7 +1056,7 @@ function stratis2_start() {
};

client.features.stratis = true;
client.stratis_pools = client.stratis_manager.client.proxies("org.storage.stratis2.pool.r1",
client.stratis_pools = client.stratis_manager.client.proxies("org.storage.stratis2.pool.r3",
"/org/storage/stratis2",
{ watch: false });
client.stratis_blockdevs = client.stratis_manager.client.proxies("org.storage.stratis2.blockdev.r2",
Expand Down Expand Up @@ -1144,6 +1144,7 @@ function stratis2_fetch_manager_properties(proxy) {
proxy.StoppedPools[uuid] = {
devs: l.devs,
key_description: { t: "(bv)", v: [true, l.key_description] },
clevis_info: { t: "(bv)", v: [true, l.clevis_info] },
};
}
client.update();
Expand All @@ -1156,15 +1157,20 @@ function stratis2_fetch_pool_properties(proxy) {
proxy.TotalPhysicalUsed = [false, ""];
if (!proxy.KeyDescription)
proxy.KeyDescription = [false, ""];
stratis2_fetch_properties(proxy, ["TotalPhysicalSize", "TotalPhysicalUsed", "KeyDescription"]).then(values => {
if (values.TotalPhysicalSize)
proxy.TotalPhysicalSize = values.TotalPhysicalSize;
if (values.TotalPhysicalUsed)
proxy.TotalPhysicalUsed = [true, values.TotalPhysicalUsed];
if (values.KeyDescription)
proxy.KeyDescription = [true, values.KeyDescription];
client.update();
});
if (!proxy.ClevisInfo)
proxy.ClevisInfo = [false, ["", ""]];
stratis2_fetch_properties(proxy, ["TotalPhysicalSize", "TotalPhysicalUsed", "KeyDescription", "ClevisInfo"])
.then(values => {
if (values.TotalPhysicalSize)
proxy.TotalPhysicalSize = values.TotalPhysicalSize;
if (values.TotalPhysicalUsed)
proxy.TotalPhysicalUsed = [true, values.TotalPhysicalUsed];
if (values.KeyDescription)
proxy.KeyDescription = [true, values.KeyDescription];
if (values.ClevisInfo)
proxy.ClevisInfo = [true, values.ClevisInfo];
client.update();
});
}

function stratis2_fetch_pool_properties_by_path(path) {
Expand Down Expand Up @@ -1225,7 +1231,7 @@ function stratis2_fixup_pool_notifications(data) {
const props = data[path][iface];
if (props && props.Name) {
// The pool at 'path' got renamed.
fixup_data[path] = { "org.storage.stratis2.pool.r1": { Name: props.Name } };
fixup_data[path] = { "org.storage.stratis2.pool.r3": { Name: props.Name } };
for (const fsys of client.stratis_pool_filesystems[path]) {
fixup_data[fsys.path] = {
"org.storage.stratis2.filesystem": {
Expand Down
51 changes: 26 additions & 25 deletions pkg/storaged/crypto-keyslots.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const _ = cockpit.gettext;
/* Tang advertisement utilities
*/

function get_tang_adv(url) {
export function get_tang_adv(url) {
return cockpit.spawn(["curl", "-sSf", url + "/adv"], { err: "message" })
.then(JSON.parse)
.catch(error => {
Expand Down Expand Up @@ -487,7 +487,7 @@ function parse_url(url) {
}
}

function validate_url(url) {
export function validate_url(url) {
if (url.length === 0)
return _("Address cannot be empty");
if (!parse_url(url))
Expand Down Expand Up @@ -606,35 +606,36 @@ function add_or_update_tang(dlg, vals, block, url, adv, old_key, passphrase) {
.catch(request_passphrase_on_error_handler(dlg, vals, passphrase, block));
}

function edit_tang_adv(client, block, key, url, adv, passphrase) {
export const TangKeyVerification = ({ url, adv }) => {
const parsed = parse_url(url);
const cmd = cockpit.format("ssh $0 tang-show-keys $1", parsed.hostname, parsed.port);

const sigkey_thps = compute_sigkey_thps(tang_adv_payload(adv));

return <>
<p>{_("Make sure the key hash from the Tang server matches one of the following:")}</p>

<h2 className="sigkey-heading">{_("SHA256")}</h2>
{ sigkey_thps.map(s => <p key={s} className="sigkey-hash">{s.sha256}</p>) }

<h2 className="sigkey-heading">{_("SHA1")}</h2>
{ sigkey_thps.map(s => <p key={s} className="sigkey-hash">{s.sha1}</p>) }

<p>
{_("Manually check with SSH: ")}
<ClipboardCopy hoverTip={_("Copy to clipboard")}
clickTip={_("Successfully copied to clipboard!")}
variant="inline-compact"
isCode>
{cmd}
</ClipboardCopy>
</p>
</>;
};

function edit_tang_adv(client, block, key, url, adv, passphrase) {
const dlg = dialog_open({
Title: _("Verify key"),
Body: (
<>
<p>{_("Make sure the key hash from the Tang server matches one of the following:")}</p>

<h2 className="sigkey-heading">{_("SHA256")}</h2>
{ sigkey_thps.map(s => <p key={s} className="sigkey-hash">{s.sha256}</p>) }

<h2 className="sigkey-heading">{_("SHA1")}</h2>
{ sigkey_thps.map(s => <p key={s} className="sigkey-hash">{s.sha1}</p>) }

<p>
{_("Manually check with SSH: ")}
<ClipboardCopy hoverTip={_("Copy to clipboard")}
clickTip={_("Successfully copied to clipboard!")}
variant="inline-compact"
isCode>
{cmd}
</ClipboardCopy>
</p>
</>
),
Body: <TangKeyVerification url={url} adv={adv} />,
Fields: existing_passphrase_fields(_("Saving a new passphrase requires unlocking the disk. Please provide a current disk passphrase.")),
Action: {
Title: _("Trust key"),
Expand Down
Loading

0 comments on commit eadabc0

Please sign in to comment.