in export/securedrop_export/disk/cli.py [0:0]
def _get_supported_volume(self, device: dict) -> Volume | MountedVolume | None:
"""
Given JSON-formatted lsblk output for one device, determine if it
is suitably partitioned and return it to be used for export,
mounting it if possible.
Supported volumes:
* Unlocked Veracrypt drives
* Locked or unlocked LUKS drives
* No more than one encrypted partition (multiple non-encrypted partitions
are OK as they will be ignored).
Note: It would be possible to support other unlocked encrypted drives, as long as
udisks2 can tell they contain an encrypted partition.
"""
device_name = device.get("name")
device_fstype = device.get("fstype")
vol = Volume(f"{_DEV_PREFIX}{device_name}", EncryptionScheme.UNKNOWN)
if device_fstype == "crypto_LUKS":
logger.debug(f"{device_name} is LUKS-encrypted")
vol.encryption = EncryptionScheme.LUKS
children = device.get("children")
if children:
if len(children) != 1:
logger.error(f"Unexpected volume format on {vol.device_name}")
return None
elif children[0].get("type") != "crypt":
return None
else:
# It's an unlocked drive, possibly mounted
mapped_name = f"{_DEVMAPPER_PREFIX}{children[0].get('name')}"
# Unlocked VC/TC drives will still have EncryptionScheme.UNKNOWN;
# see if we can do better
if vol.encryption == EncryptionScheme.UNKNOWN:
vol.encryption = self._is_it_veracrypt(vol)
# To opportunistically mount any unlocked encrypted partition
# (i.e. third-party devices such as IronKeys), remove this condition.
if vol.encryption in (EncryptionScheme.LUKS, EncryptionScheme.VERACRYPT):
logger.debug(f"{vol.device_name} encryption scheme is supported")
if children[0].get("mountpoint"):
logger.debug(f"{vol.device_name} is mounted")
return MountedVolume(
device_name=vol.device_name,
unlocked_name=mapped_name,
encryption=vol.encryption,
mountpoint=children[0].get("mountpoint"),
)
else:
logger.debug(f"{device_name} is unlocked but unmounted; attempting mount")
return self._mount_volume(vol, mapped_name)
# Locked VeraCrypt drives are rejected here (EncryptionScheme.UNKNOWN)
if vol.encryption in (EncryptionScheme.LUKS, EncryptionScheme.VERACRYPT):
logger.debug(f"{vol.device_name} is supported export target")
return vol
else:
logger.debug(f"No suitable volume found on {vol.device_name}")
return None