From 2b20741a04ce4de54dda044327372139e00657aa Mon Sep 17 00:00:00 2001 From: imgrant Date: Mon, 14 Dec 2015 13:39:17 +0000 Subject: [PATCH 01/10] Minor code tidying. Refactor some code to avoid duplicated calls that led to typo bug in v2.0.0. Tweak description of devices/containers. Tweak filename for header backups. --- debian/changelog | 8 +++ usr/share/openmediavault/engined/rpc/luks.inc | 62 ++++++++++++------- usr/share/php/openmediavault/luks.inc | 19 ++++-- 3 files changed, 62 insertions(+), 27 deletions(-) diff --git a/debian/changelog b/debian/changelog index c74ab6c..32e25d0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +openmediavault-luksencryption (2.1.0) UNRELEASED; urgency=medium + + * Refactor some code to avoid duplicated calls that led to typo bug in v2.0.0. + * Tweak description of devices/containers. + * Tweak filename for header backups. + + -- OpenMediaVault Plugin Developers Mon, 14 Dec 2015 13:37:13 +0000 + openmediavault-luksencryption (2.0.1) unstable; urgency=high * Bugfix: typo in createContainer() caused creating containers with passphrases to fail. diff --git a/usr/share/openmediavault/engined/rpc/luks.inc b/usr/share/openmediavault/engined/rpc/luks.inc index a57822e..c15fd56 100644 --- a/usr/share/openmediavault/engined/rpc/luks.inc +++ b/usr/share/openmediavault/engined/rpc/luks.inc @@ -276,11 +276,14 @@ class OMVRpcServiceLuksMgmt extends OMVRpcServiceAbstract { // Check that the container is not already open, then use // the supplied passphrase or key file to unlock it if not. if (FALSE === $luks->isOpen()) { - if(isset($params['keyfile']) && !empty($params['keyfile'])) - $success = $luks->open($params['keyfile'], TRUE); - else - $success = $luks->open($params['passphrase']); - if ($success === FALSE) { + if(isset($params['keyfile']) && !empty($params['keyfile'])) { + $key = $params['keyfile']; + $keyIsFile = TRUE; + } else { + $key = $params['passphrase']; + $keyIsFile = FALSE; + } + if ($luks->open($key, $keyIsFile) === FALSE) { throw new OMVException(OMVErrorMsg::E_EXEC_MISC, sprintf(gettext("Unable to unlock encrypted device: %s"), $luks->getLastError())); @@ -482,14 +485,14 @@ class OMVRpcServiceLuksMgmt extends OMVRpcServiceAbstract { } // Create the container. $luks = new OMVLuksContainer($sd->getDeviceFile()); - if(isset($params['keyfile']) && !empty($params['keyfile'])) - $success = $luks->create($sd->getDeviceFile(), - $params['keyfile'], - TRUE); - else - $success = $luks->create($sd->getDeviceFile(), - $params['passphrase']); - if ($success === FALSE) { + if(isset($params['keyfile']) && !empty($params['keyfile'])) { + $key = $params['keyfile']; + $keyIsFile = TRUE; + } else { + $key = $params['passphrase']; + $keyIsFile = FALSE; + } + if ($luks->create($key, $keyIsFile) === FALSE) { throw new OMVException(OMVErrorMsg::E_EXEC_MISC, sprintf( gettext("Unable to create the encrypted device: %s"), $luks->getLastError())); @@ -747,11 +750,14 @@ class OMVRpcServiceLuksMgmt extends OMVRpcServiceAbstract { $params['devicefile'])); } // Remove the key - if(isset($params['keyfile']) && !empty($params['keyfile'])) - $success = $luks->removeKey($params['keyfile'], TRUE); - else - $success = $luks->removeKey($params['passphrase']); - if ($success === FALSE) { + if(isset($params['keyfile']) && !empty($params['keyfile'])) { + $key = $params['keyfile']; + $keyIsFile = TRUE; + } else { + $key = $params['passphrase']; + $keyIsFile = FALSE; + } + if ($luks->removeKey($key, $keyIsFile) === FALSE) { throw new OMVException(OMVErrorMsg::E_EXEC_MISC, sprintf(gettext("Unable to remove the key from the encrypted device: %s"), $luks->getLastError())); @@ -871,12 +877,12 @@ class OMVRpcServiceLuksMgmt extends OMVRpcServiceAbstract { "devicefile":{'.$GLOBALS['OMV_JSONSCHEMA_DEVICEFILE'].'} } }'); - // Check if container exists. + // Validate the container $luks = new OMVLuksContainer($params['devicefile']); - if (FALSE === $luks->exists()) { + if (is_null($luks) || !$luks->exists()) { throw new OMVException(OMVErrorMsg::E_MISC_FAILURE, - sprintf(gettext("No encryption found on '%s'"), - $params['devicefile'])); + sprintf(gettext("LUKS container on '%s' not found"), + $params['devicefile'])); } // Extract the header to a temporary location and modify the // file mode/owner to allow the WebGUI PHP backend to unlink it. @@ -892,9 +898,19 @@ class OMVRpcServiceLuksMgmt extends OMVRpcServiceAbstract { chmod($tmpFilePath, 0600); chgrp($tmpFilePath, $GLOBALS['OMV_WEBGUI_FILE_OWNERGROUP_NAME']); chown($tmpFilePath, $GLOBALS['OMV_WEBGUI_FILE_OWNERGROUP_NAME']); + // Build filename for file + $fn = preg_replace('/\s+/', + '-', + array( + $luks->getVendor(), + $luks->getModel(), + $luks->getSerialNumber(), + $luks->getUuid() + ) + ); // Return values required by generic download RPC implementation. return array( - "filename" => "LUKS_header_".$luks->getUuid().".bak", + "filename" => "LUKS_header_".implode('_', $fn).".bak", "filepath" => $tmpFilePath, "contenttype" => "application/octet-stream", "unlink" => TRUE diff --git a/usr/share/php/openmediavault/luks.inc b/usr/share/php/openmediavault/luks.inc index 81807fb..e94c7ad 100644 --- a/usr/share/php/openmediavault/luks.inc +++ b/usr/share/php/openmediavault/luks.inc @@ -345,8 +345,8 @@ class OMVLuksContainer extends OMVStorageDeviceAbstract { public function getDescription() { if ($this->getData() === FALSE) return FALSE; - return sprintf(gettext("LUKS encrypted device %s [%s, %s]"), - $this->getDecryptedName(), + return sprintf(gettext("LUKS encrypted device (%s) [%s, %s]"), + $this->getModel(), $this->getDeviceFile(), binary_format($this->getSize())); } @@ -877,13 +877,24 @@ class OMVStorageDeviceLUKS extends OMVStorageDeviceDM { return OMVLuksContainer::isLuksContainer($dev); } + /** + * Get the underlying device model. + * @return The device model, otherwise an empty string. + */ + public function getModel() { + if(FALSE === ($luks = $this->getContainer())) + return ""; + return $luks->getModel(); + } + /** * Get the description of the LUKS container. * @return The LUKS container description, FALSE on failure. */ public function getDescription() { - return sprintf(gettext("LUKS encrypted device %s [%s, %s]"), - $this->getLuksEncryptedDeviceName(), + return sprintf(gettext("LUKS encrypted container on %s (%s) [%s, %s]"), + $this->getCanonicalLuksEncryptedDeviceFile(), + $this->getModel(), $this->getDeviceFile(), binary_format($this->getSize())); } From 5e546206665ac565cf8313bc8bf67c1941cbd074 Mon Sep 17 00:00:00 2001 From: imgrant Date: Wed, 6 Jan 2016 11:32:20 +0000 Subject: [PATCH 02/10] Fix bug in lsblk -l and -r options are mutually incompatible, previously lsblk didn't complain, but the latest version in Debian Jessie (OMV 3.0) does. --- usr/share/php/openmediavault/luks.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/share/php/openmediavault/luks.inc b/usr/share/php/openmediavault/luks.inc index e94c7ad..04c27dc 100644 --- a/usr/share/php/openmediavault/luks.inc +++ b/usr/share/php/openmediavault/luks.inc @@ -39,7 +39,7 @@ class OMVLuksContainers extends OMVObject { * ) */ public static function enumerate() { - $cmd = "export LANG=C; lsblk -o kname,fstype -lbnr ". + $cmd = "export LANG=C; lsblk -o kname,fstype -bnr ". "2>/dev/null ". "| grep crypto_LUKS | awk '{print \"/dev/\"\$1}' "; @OMVUtil::exec($cmd, $output, $result); From d701aeddcf01915958061cd7a7c46ce44928eac9 Mon Sep 17 00:00:00 2001 From: imgrant Date: Wed, 6 Jan 2016 11:50:40 +0000 Subject: [PATCH 03/10] Fix regression bug in container creation. --- usr/share/php/openmediavault/luks.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/share/php/openmediavault/luks.inc b/usr/share/php/openmediavault/luks.inc index 04c27dc..d1ed043 100644 --- a/usr/share/php/openmediavault/luks.inc +++ b/usr/share/php/openmediavault/luks.inc @@ -361,7 +361,7 @@ class OMVLuksContainer extends OMVStorageDeviceAbstract { * the key file). Defaults to FALSE. * @return TRUE if successful, otherwise FALSE. */ - public function create($devicefile, $key, $keyIsFile=FALSE) { + public function create($key, $keyIsFile=FALSE) { switch($keyIsFile) { case TRUE: $cmd = sprintf("export LANG=C; cryptsetup luksFormat %s ". From 819294426ddce6918106bd4bd1eba62b2a4cbeff Mon Sep 17 00:00:00 2001 From: imgrant Date: Wed, 6 Jan 2016 14:14:33 +0000 Subject: [PATCH 04/10] Activate LVM volume groups after unlocking in LVM-on-LUKS situations --- usr/share/openmediavault/engined/rpc/luks.inc | 205 +++++++++++------- 1 file changed, 132 insertions(+), 73 deletions(-) diff --git a/usr/share/openmediavault/engined/rpc/luks.inc b/usr/share/openmediavault/engined/rpc/luks.inc index c15fd56..96984ca 100644 --- a/usr/share/openmediavault/engined/rpc/luks.inc +++ b/usr/share/openmediavault/engined/rpc/luks.inc @@ -28,6 +28,7 @@ require_once("openmediavault/functions.inc"); require_once("openmediavault/luks.inc"); require_once("openmediavault/rpcservice.inc"); require_once("openmediavault/notify.inc"); +include_once("openmediavault/lvm.inc"); class OMVRpcServiceLuksMgmt extends OMVRpcServiceAbstract { @@ -289,84 +290,142 @@ class OMVRpcServiceLuksMgmt extends OMVRpcServiceAbstract { $luks->getLastError())); } } + /* Downstream operations with the decrypted container */ + $sdluks = new OMVStorageDeviceLUKS($luks->getDecryptedDeviceFile()); + $df = $sdluks->getDeviceFile(); + // If the container contains an LVM physical volume, determine the + // volume group and activate it (otherwise the logical volume and any + // filesystem on it won't be accessible) + if (class_exists("OMVLvmPhysicalVolume")) { + // Use LVM plugin if it's installed to get VG name + $pv = new OMVLvmPhysicalVolume($df); + if (TRUE === $pv->exists()) { + $vgName = $pv->getVGName(); + } + } else { + // Fall back to manual method without LVM plugin + $cmd = sprintf("export LANG=C; pvdisplay --noheadings ". + "-C -o vg_name %s ", + escapeshellarg($df)); + @OMVUtil::exec($cmd, $output, $result); + if($result === 0) { + $vgName = trim($output[0]); + } + } + // PV/VG was found - activate the VG, set devicefile to LV via + // LVM plugin if available - although LVM/udev seems to + // automatically mount filesystems in fstab from logical + // volumes when activated, so probably not strictly necessary. + if (isset($vgName)) { + $this->debug(sprintf("%s contains an LVM2 PV, part of VG: %s", + $df, $vgName)); + $cmd = sprintf("export LANG=C; vgchange -a y %s ", + escapeshellarg($vgName)); + @OMVUtil::exec($cmd, $output, $result); + if($result !== 0) { + $this->debug($output); + } else { + if (class_exists("OMVLvmVolumeGroup")) { + $vg = new OMVLvmVolumeGroup($vgName); + $lvNames = $vg->getLVName(); + $fsDevs = array_map(function($lv) use ($vgName) { + return "/dev/$vgName-$lv"; + }, $lvNames); + } + } + } else { + // If not an LVM2 PV, just pass the container devicefile + $fsDevs = array($df); + } // If the container contains a (referenced) filesystem, then mount it // (unless this automounting is disabled by the global configuration // option, OMV_LUKS_MOUNT_ON_UNLOCK - see initialize() above) if(TRUE === $this->mountOnUnlock) { - $sdluks = new OMVStorageDeviceLUKS($luks->getDecryptedDeviceFile()); - $df = $sdluks->getDeviceFile(); - if(FALSE !== OMVRpc::exec("FileSystemMgmt", "hasFilesystem", - array("devicefile" => $df), $context)) { - if(FALSE !== ($meObject = OMVRpc::exec("FsTab", "getByFsName", - array("id" => $df), $context))) { - switch (strtolower($meObject['type'])) { - case "btrfs": - /** - * Check if the unlocked device is part of a multi- - * device BTRFS filesystem, and don't attempt to mount - * it if it's not ready (not all devices are available, - * e.g. if more containers must be unlocked first, wait - * until they are all open). - * Note: using 'btrfs device ready' only works for the - * first time devices are opened - even if LUKS devices - * that are part of a multi-device BTRFS filesystem are - * later closed, some information is cached and so btrfs - * subsequently always reports the filesystem as ready. - * Hence, this workaround checks the number of devices - * online for the filesystem via 'btrfs filesystem show' - * instead, which should be more reliable. - * TODO: submit a patch to the core BTRFS backend that - * exposes this in a class function instead? - */ - // Find out how many devices are in the filesystem - $cmd = sprintf("export LANG=C; btrfs filesystem ". - "show %s | grep 'Total devices' | ". - "awk '{print $3}'", - escapeshellarg($meObject['uuid'])); - @OMVUtil::exec($cmd, $output, $result); - if($result !== 0) { - $this->setLastError($output); - continue; - } - $totalDevices = (int)$output[0]; - // If the fs has fewer than one device (an error - // of some kind occurred), skip mounting - if($totalDevices < 1) - continue; - unset($cmd, $output, $result); - // Find out how many are online - $cmd = sprintf("export LANG=C; btrfs filesystem ". - "show %s | grep 'devid' | wc -l", - escapeshellarg($meObject['uuid'])); - @OMVUtil::exec($cmd, $output, $result); - if($result !== 0) { - $this->setLastError($output); - continue; - } - $availableDevices = (int)$output[0]; - // If not all devices are online, skip mounting - if($availableDevices !== $totalDevices) - continue; - unset($cmd, $output, $result); - case "ext2": - case "ext3": - case "ext4": - case "jfs": - case "xfs": - case "hfsplus": - case "reiserfs": - case "iso9660": - case "udf": - case "vfat": - case "ntfs": - default: - OMVRpc::exec("FileSystemMgmt", "mount", - array( - "id" => $meObject['fsname'], - "fstab" => FALSE - ), - $context); + foreach ($fsDevs as $dev) { + $this->mountContainerFS($dev, $context); + } + } + } + + /** + * Helper function for mounting filesystems inside containers on unlocking. + * @param devicefile The decrypted block special device of the + * filesystem (inside the LUKS container) to mount. + * @param context The context of the caller. + * @return None. + */ + private function mountContainerFS($deviceFile, $context) { + if(FALSE !== OMVRpc::exec("FileSystemMgmt", "hasFilesystem", + array("devicefile" => $deviceFile), $context)) { + if(FALSE !== ($meObject = OMVRpc::exec("FsTab", "getByFsName", + array("id" => $deviceFile), $context))) { + switch (strtolower($meObject['type'])) { + case "btrfs": + /** + * Check if the unlocked device is part of a multi- + * device BTRFS filesystem, and don't attempt to mount + * it if it's not ready (not all devices are available, + * e.g. if more containers must be unlocked first, wait + * until they are all open). + * Note: using 'btrfs device ready' only works for the + * first time devices are opened - even if LUKS devices + * that are part of a multi-device BTRFS filesystem are + * later closed, some information is cached and so btrfs + * subsequently always reports the filesystem as ready. + * Hence, this workaround checks the number of devices + * online for the filesystem via 'btrfs filesystem show' + * instead, which should be more reliable. + * TODO: submit a patch to the core BTRFS backend that + * exposes this in a class function instead? + */ + // Find out how many devices are in the filesystem + $cmd = sprintf("export LANG=C; btrfs filesystem ". + "show %s | grep 'Total devices' | ". + "awk '{print $3}'", + escapeshellarg($meObject['uuid'])); + @OMVUtil::exec($cmd, $output, $result); + if($result !== 0) { + $this->setLastError($output); + continue; + } + $totalDevices = (int)$output[0]; + // If the fs has fewer than one device (an error + // of some kind occurred), skip mounting + if($totalDevices < 1) + continue; + unset($cmd, $output, $result); + // Find out how many are online + $cmd = sprintf("export LANG=C; btrfs filesystem ". + "show %s | grep 'devid' | wc -l", + escapeshellarg($meObject['uuid'])); + @OMVUtil::exec($cmd, $output, $result); + if($result !== 0) { + $this->setLastError($output); + continue; } + $availableDevices = (int)$output[0]; + // If not all devices are online, skip mounting + if($availableDevices !== $totalDevices) + continue; + unset($cmd, $output, $result); + case "ext2": + case "ext3": + case "ext4": + case "jfs": + case "xfs": + case "hfsplus": + case "reiserfs": + case "iso9660": + case "udf": + case "vfat": + case "ntfs": + default: + OMVRpc::exec("FileSystemMgmt", "mount", + array( + "id" => $meObject['fsname'], + "fstab" => FALSE + ), + $context); } } } From 7c9dfa312664b53869badb570b6f1aff94ceca02 Mon Sep 17 00:00:00 2001 From: imgrant Date: Wed, 6 Jan 2016 14:45:56 +0000 Subject: [PATCH 05/10] Use blkid instead of lsblk for enumerating LUKS devices Avoids duplicate entries for, e.g. partitions in LUKS-on-RAID situation. It's also simpler! --- usr/share/php/openmediavault/luks.inc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/usr/share/php/openmediavault/luks.inc b/usr/share/php/openmediavault/luks.inc index d1ed043..21e15a7 100644 --- a/usr/share/php/openmediavault/luks.inc +++ b/usr/share/php/openmediavault/luks.inc @@ -39,9 +39,7 @@ class OMVLuksContainers extends OMVObject { * ) */ public static function enumerate() { - $cmd = "export LANG=C; lsblk -o kname,fstype -bnr ". - "2>/dev/null ". - "| grep crypto_LUKS | awk '{print \"/dev/\"\$1}' "; + $cmd = "export LANG=C; blkid -t TYPE=crypto_LUKS -o device 2>/dev/null"; @OMVUtil::exec($cmd, $output, $result); if($result !== 0) return FALSE; From 4821552b2b89ffbf716e6cb76925a721760e177e Mon Sep 17 00:00:00 2001 From: imgrant Date: Wed, 6 Jan 2016 14:49:16 +0000 Subject: [PATCH 06/10] Cosmetic tweak for containers on devices without model information i.e. partitions instead of raw disks. --- usr/share/php/openmediavault/luks.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/share/php/openmediavault/luks.inc b/usr/share/php/openmediavault/luks.inc index 21e15a7..ad533ee 100644 --- a/usr/share/php/openmediavault/luks.inc +++ b/usr/share/php/openmediavault/luks.inc @@ -890,9 +890,9 @@ class OMVStorageDeviceLUKS extends OMVStorageDeviceDM { * @return The LUKS container description, FALSE on failure. */ public function getDescription() { - return sprintf(gettext("LUKS encrypted container on %s (%s) [%s, %s]"), + return sprintf(gettext("LUKS encrypted container on %s %s [%s, %s]"), $this->getCanonicalLuksEncryptedDeviceFile(), - $this->getModel(), + ($this->getModel()) ? '('.$this->getModel().')' : '', $this->getDeviceFile(), binary_format($this->getSize())); } From 0c98b4b3474963c68bb60ade52af621807897bbd Mon Sep 17 00:00:00 2001 From: imgrant Date: Wed, 6 Jan 2016 14:56:29 +0000 Subject: [PATCH 07/10] Update changelog --- debian/changelog | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 32e25d0..c09e892 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,13 @@ -openmediavault-luksencryption (2.1.0) UNRELEASED; urgency=medium +openmediavault-luksencryption (2.1.0) unstable; urgency=high + * Tested on OMV 3.0. + * Activate LVM volume groups after unlocking for LVM-on-LUKS. + * Fix for duplicate entries in the case of, e.g. partitions on RAID devices. * Refactor some code to avoid duplicated calls that led to typo bug in v2.0.0. * Tweak description of devices/containers. * Tweak filename for header backups. - -- OpenMediaVault Plugin Developers Mon, 14 Dec 2015 13:37:13 +0000 + -- OpenMediaVault Plugin Developers Wed, 06 Jan 2016 14:53:13 +0000 openmediavault-luksencryption (2.0.1) unstable; urgency=high From f0a38f257947cbc458beadf4e3832163df2f9565 Mon Sep 17 00:00:00 2001 From: imgrant Date: Wed, 6 Jan 2016 15:03:18 +0000 Subject: [PATCH 08/10] Tweak device description --- usr/share/php/openmediavault/luks.inc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usr/share/php/openmediavault/luks.inc b/usr/share/php/openmediavault/luks.inc index ad533ee..a0e1b2b 100644 --- a/usr/share/php/openmediavault/luks.inc +++ b/usr/share/php/openmediavault/luks.inc @@ -343,8 +343,8 @@ class OMVLuksContainer extends OMVStorageDeviceAbstract { public function getDescription() { if ($this->getData() === FALSE) return FALSE; - return sprintf(gettext("LUKS encrypted device (%s) [%s, %s]"), - $this->getModel(), + return sprintf(gettext("LUKS encrypted device %s[%s, %s]"), + ($this->getModel()) ? '('.$this->getModel().') ' : '', $this->getDeviceFile(), binary_format($this->getSize())); } @@ -890,9 +890,9 @@ class OMVStorageDeviceLUKS extends OMVStorageDeviceDM { * @return The LUKS container description, FALSE on failure. */ public function getDescription() { - return sprintf(gettext("LUKS encrypted container on %s %s [%s, %s]"), + return sprintf(gettext("LUKS encrypted container on %s %s[%s, %s]"), $this->getCanonicalLuksEncryptedDeviceFile(), - ($this->getModel()) ? '('.$this->getModel().')' : '', + ($this->getModel()) ? '('.$this->getModel().') ' : '', $this->getDeviceFile(), binary_format($this->getSize())); } From 181c38ae71ee950e26ab23161bd781b0e90f369e Mon Sep 17 00:00:00 2001 From: imgrant Date: Wed, 13 Jan 2016 11:01:00 +0000 Subject: [PATCH 09/10] Fixed a bug where no LUKS devices would cause a (harmless) error message. More info: blkid -t returns code 2 when no devices found. --- debian/changelog | 6 ++++++ usr/share/php/openmediavault/luks.inc | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index c09e892..0f7ce28 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +openmediavault-luksencryption (2.1.1) unstable; urgency=medium + + * Bugfix: no LUKS devices present would cause an error message. + + -- OpenMediaVault Plugin Developers Wed, 13 Jan 2016 10:59:49 +0000 + openmediavault-luksencryption (2.1.0) unstable; urgency=high * Tested on OMV 3.0. diff --git a/usr/share/php/openmediavault/luks.inc b/usr/share/php/openmediavault/luks.inc index a0e1b2b..8ce3bf8 100644 --- a/usr/share/php/openmediavault/luks.inc +++ b/usr/share/php/openmediavault/luks.inc @@ -41,7 +41,7 @@ class OMVLuksContainers extends OMVObject { public static function enumerate() { $cmd = "export LANG=C; blkid -t TYPE=crypto_LUKS -o device 2>/dev/null"; @OMVUtil::exec($cmd, $output, $result); - if($result !== 0) + if(!in_array($result, array(0,2), TRUE)) return FALSE; $list = array(); // Parse command output: From eb39c4a7f194b7dc395ee890842e9f4d2ba99d6e Mon Sep 17 00:00:00 2001 From: imgrant Date: Fri, 5 Feb 2016 15:18:00 +0000 Subject: [PATCH 10/10] Fix for decrypted device name with LUKS-on-LVM. --- debian/changelog | 6 ++++++ usr/share/php/openmediavault/luks.inc | 25 +++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 0f7ce28..41fde53 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +openmediavault-luksencryption (2.1.2) stable; urgency=medium + + * Bugfix: opening LUKS-on-LVM devices would fail. + + -- OpenMediaVault Plugin Developers Fri, 05 Feb 2016 14:42:59 +0000 + openmediavault-luksencryption (2.1.1) unstable; urgency=medium * Bugfix: no LUKS devices present would cause an error message. diff --git a/usr/share/php/openmediavault/luks.inc b/usr/share/php/openmediavault/luks.inc index 8ce3bf8..d5d64da 100644 --- a/usr/share/php/openmediavault/luks.inc +++ b/usr/share/php/openmediavault/luks.inc @@ -146,6 +146,15 @@ class OMVLuksContainer extends OMVStorageDeviceAbstract { if($this->dataCached !== FALSE) return TRUE; + // Reset cached data + $this->uuid = ""; + $this->isOpen = FALSE; + $this->headerInfo = ""; + $this->usedKeySlots = 0; + $this->freeKeySlots = 8; + $this->deviceMapperDeviceFile = ""; + $this->deviceMapperName = ""; + // Look up the UUID for the LUKS container $cmd = sprintf("export LANG=C; cryptsetup luksUUID %s", $this->getDeviceFile()); @@ -336,6 +345,18 @@ class OMVLuksContainer extends OMVStorageDeviceAbstract { return $this->deviceMapperName; } + /** + * Helper function for determining a name for the decrypted device. + * Avoids naming problems with, e.g. LUKS-on-LVM where the devicefile + * is of the form /dev/mapper/VG-LV. + * @return A sanitised string for use as the mapped device name. + */ + private function generateDecryptedName() { + $dev = $this->getDeviceName(); + $dev = preg_replace("/^mapper\//", "", $dev); + return str_replace("/", "-", $dev); + } + /** * Get the description of the LUKS container. * @return The LUKS container description, FALSE on failure. @@ -477,7 +498,7 @@ class OMVLuksContainer extends OMVStorageDeviceAbstract { $cmd = sprintf("export LANG=C; cryptsetup luksOpen %s ". "%s-crypt --key-file %s 2>&1", escapeshellarg($this->getDeviceFile()), - escapeshellarg($this->getDeviceName()), + escapeshellarg($this->generateDecryptedName()), escapeshellarg($key)); break; case FALSE: @@ -486,7 +507,7 @@ class OMVLuksContainer extends OMVStorageDeviceAbstract { "cryptsetup luksOpen %s %s-crypt --key-file=- 2>&1", escapeshellarg($key), escapeshellarg($this->getDeviceFile()), - escapeshellarg($this->getDeviceName())); + escapeshellarg($this->generateDecryptedName())); } @OMVUtil::exec($cmd, $output, $result); if ($result !== 0) {