Skip to content

Commit

Permalink
locations: Ask again for password on encryption failures
Browse files Browse the repository at this point in the history
This sadly requires parsing the error strings since there are not good
APIs yet, but that's how upstream handles this too, so let's accept it
for now.

See: https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3300
  • Loading branch information
3v1n0 committed May 5, 2024
1 parent 8a73fa6 commit 0b89cd5
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions locations.js
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,12 @@ class MountableVolumeAppInfo extends LocationAppInfo {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED))
this._notifyActionError(action, e.message);

if (this._isEncryptedVolumeMountError(e)) {
delete this._currentAction;
operation.close();
return this.launchAction(action);
}

if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
logError(e, 'Impossible to %s removable %s'.format(action,
removable.get_name()));
Expand All @@ -669,6 +675,39 @@ class MountableVolumeAppInfo extends LocationAppInfo {
operation.close();
}
}

_isEncryptedVolumeMountError(error) {
// FIXME: we will always get G_IO_ERROR_FAILED from the gvfs udisks
// backend, see https://bugs.freedesktop.org/show_bug.cgi?id=51271

if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED))
return false;

// cryptsetup
if (error.message.includes('No key available with this passphrase'))
return true;

// udisks (no password)
if (error.message.includes('No key available to unlock device'))
return true;

// libblockdev wrong password opening LUKS device
if (error.message.includes('Failed to activate device: Incorrect passphrase'))
return true;

// cryptsetup returns EINVAL in many cases, including wrong TCRYPT password/parameters
if (error.message.includes('Failed to load device\'s parameters: Invalid argument') ||
error.message.includes(`Failed to load device's parameters: ${GLib.strerror(22 /* EINVAL */)}`))
return true;

// cryptsetup returns EPERM when the TCRYPT header can't be decrypted
// with the provided password/parameters.
if (error.message.includes('Failed to load device\'s parameters: Operation not permitted') ||
error.message.includes(`Failed to load device's parameters: ${GLib.strerror(1 /* EPERM */)}`))
return true;

return false;
}
});

const TrashAppInfo = GObject.registerClass({
Expand Down

0 comments on commit 0b89cd5

Please sign in to comment.