From db92f0e3658a080b060966ab103f8d4013dcf1f1 Mon Sep 17 00:00:00 2001 From: Florent BEAUCHAMP Date: Thu, 21 Sep 2023 11:18:44 +0200 Subject: [PATCH] fix(vhd-lib): VhdFile implementation is not compatible with encrypted remote (#7045) --- CHANGELOG.unreleased.md | 2 ++ packages/vhd-lib/Vhd/VhdFile.js | 11 +++++++---- packages/vhd-lib/openVhd.js | 19 +++++++++++++------ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 14605b3a7..b93677de3 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -17,6 +17,7 @@ - [Google/GitHub Auth] Fix `Internal Server Error` (xo-server: `Cannot read properties of undefined (reading 'id')`) when logging in with Google or GitHub [Forum#7729](https://xcp-ng.org/forum/topic/7729) (PRs [#7031](https://github.com/vatesfr/xen-orchestra/pull/7031) [#7032](https://github.com/vatesfr/xen-orchestra/pull/7032)) - [Jobs] Fix schedules not being displayed on first load [#6968](https://github.com/vatesfr/xen-orchestra/issues/6968) (PR [#7034](https://github.com/vatesfr/xen-orchestra/pull/7034)) - [OVA Export] Fix support of disks with more than 8.2GiB of content (PR [#7047](https://github.com/vatesfr/xen-orchestra/pull/7047)) +- [Backup] Fix `VHDFile implementation is not compatible with encrypted remote` when using VHD directory with encryption (PR [#7045](https://github.com/vatesfr/xen-orchestra/pull/7045)) ### Packages to release @@ -34,6 +35,7 @@ +- vhd-lib minor - xo-server patch - xo-server-auth-github patch - xo-server-auth-google patch diff --git a/packages/vhd-lib/Vhd/VhdFile.js b/packages/vhd-lib/Vhd/VhdFile.js index 376419181..f5c0501eb 100644 --- a/packages/vhd-lib/Vhd/VhdFile.js +++ b/packages/vhd-lib/Vhd/VhdFile.js @@ -83,9 +83,6 @@ exports.VhdFile = class VhdFile extends VhdAbstract { } static async open(handler, path, { flags, checkSecondFooter = true } = {}) { - if (handler.isEncrypted) { - throw new Error(`VHDFile implementation is not compatible with encrypted remote`) - } const fd = await handler.openFile(path, flags ?? 'r+') const vhd = new VhdFile(handler, fd) // openning a file for reading does not trigger EISDIR as long as we don't really read from it : @@ -93,7 +90,13 @@ exports.VhdFile = class VhdFile extends VhdAbstract { // EISDIR pathname refers to a directory and the access requested // involved writing (that is, O_WRONLY or O_RDWR is set). // reading the header ensure we have a well formed file immediatly - await vhd.readHeaderAndFooter(checkSecondFooter) + try { + // can throw if handler is encrypted or remote is broken + await vhd.readHeaderAndFooter(checkSecondFooter) + } catch (err) { + await handler.closeFile(fd) + throw err + } return { dispose: () => handler.closeFile(fd), value: vhd, diff --git a/packages/vhd-lib/openVhd.js b/packages/vhd-lib/openVhd.js index 8852cbafe..f9aab5b1b 100644 --- a/packages/vhd-lib/openVhd.js +++ b/packages/vhd-lib/openVhd.js @@ -6,12 +6,19 @@ const { VhdFile } = require('./Vhd/VhdFile.js') exports.openVhd = async function openVhd(handler, path, opts) { const resolved = await resolveVhdAlias(handler, path) - try { - return await VhdFile.open(handler, resolved, opts) - } catch (e) { - if (e.code !== 'EISDIR') { - throw e + + // VHD files can't be encrypted since we can't modify part of a file during merge + // + // Skip trying to open it if the remote is encrypted + if (!handler.isEncrypted) { + try { + return await VhdFile.open(handler, resolved, opts) + } catch (e) { + if (e.code !== 'EISDIR') { + throw e + } } - return await VhdDirectory.open(handler, resolved, opts) } + + return await VhdDirectory.open(handler, resolved, opts) }