* Do not stdout when menu is active

* Handle missing libfido2 gracefully

* Update

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
This commit is contained in:
Daniel Girtler 2023-07-25 19:19:14 +10:00 committed by GitHub
parent 439bb5428b
commit a548d7df70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 13 deletions

View File

@ -71,6 +71,7 @@ class DiskEncryptionMenu(AbstractSubMenu):
description=_('Use HSM to unlock encrypted drive'), description=_('Use HSM to unlock encrypted drive'),
func=lambda preset: select_hsm(preset), func=lambda preset: select_hsm(preset),
display_func=lambda x: self._display_hsm(x), display_func=lambda x: self._display_hsm(x),
preview_func=self._prev_hsm,
dependencies=['encryption_password'], dependencies=['encryption_password'],
default=self._preset.hsm_device, default=self._preset.hsm_device,
enabled=True enabled=True
@ -93,8 +94,6 @@ class DiskEncryptionMenu(AbstractSubMenu):
if device: if device:
return device.manufacturer return device.manufacturer
if not Fido2.get_fido2_devices():
return str(_('No HSM devices available'))
return None return None
def _prev_disk_layouts(self) -> Optional[str]: def _prev_disk_layouts(self) -> Optional[str]:
@ -106,6 +105,22 @@ class DiskEncryptionMenu(AbstractSubMenu):
return None return None
def _prev_hsm(self) -> Optional[str]:
try:
Fido2.get_fido2_devices()
except ValueError:
return str(_('Unable to determine fido2 devices. Is libfido2 installed?'))
fido_device: Optional[Fido2Device] = self._menu_options['HSM'].current_selection
if fido_device:
output = '{}: {}'.format(str(_('Path')), fido_device.path)
output += '{}: {}'.format(str(_('Manufacturer')), fido_device.manufacturer)
output += '{}: {}'.format(str(_('Product')), fido_device.product)
return output
return None
def select_encryption_type(preset: EncryptionType) -> Optional[EncryptionType]: def select_encryption_type(preset: EncryptionType) -> Optional[EncryptionType]:
title = str(_('Select disk encryption option')) title = str(_('Select disk encryption option'))
@ -130,7 +145,11 @@ def select_encrypted_password() -> Optional[str]:
def select_hsm(preset: Optional[Fido2Device] = None) -> Optional[Fido2Device]: def select_hsm(preset: Optional[Fido2Device] = None) -> Optional[Fido2Device]:
title = _('Select a FIDO2 device to use for HSM') title = _('Select a FIDO2 device to use for HSM')
fido_devices = Fido2.get_fido2_devices()
try:
fido_devices = Fido2.get_fido2_devices()
except ValueError:
return None
if fido_devices: if fido_devices:
choice = TableMenu(title, data=fido_devices).run() choice = TableMenu(title, data=fido_devices).run()

View File

@ -7,6 +7,7 @@ from typing import List, Optional
from .device_model import PartitionModification, Fido2Device from .device_model import PartitionModification, Fido2Device
from ..general import SysCommand, SysCommandWorker, clear_vt100_escape_codes from ..general import SysCommand, SysCommandWorker, clear_vt100_escape_codes
from ..output import error, info from ..output import error, info
from ..exceptions import SysCallError
class Fido2: class Fido2:
@ -36,13 +37,13 @@ class Fido2:
# to prevent continous reloading which will slow # to prevent continous reloading which will slow
# down moving the cursor in the menu # down moving the cursor in the menu
if not cls._loaded or reload: if not cls._loaded or reload:
ret: Optional[str] = None
try: try:
ret = SysCommand("systemd-cryptenroll --fido2-device=list").decode('UTF-8') ret: Optional[str] = SysCommand("systemd-cryptenroll --fido2-device=list").decode('UTF-8')
except: except SysCallError:
error('fido2 support is most likely not installed') error('fido2 support is most likely not installed')
raise ValueError('HSM devices can not be detected, is libfido2 installed?')
if not ret: if not ret:
error('Unable to retrieve fido2 devices')
return [] return []
fido_devices: str = clear_vt100_escape_codes(ret) # type: ignore fido_devices: str = clear_vt100_escape_codes(ret) # type: ignore

View File

@ -34,6 +34,11 @@ class MenuSelection:
class Menu(TerminalMenu): class Menu(TerminalMenu):
_menu_is_active: bool = False
@staticmethod
def is_menu_active() -> bool:
return Menu._menu_is_active
@classmethod @classmethod
def back(cls) -> str: def back(cls) -> str:
@ -260,6 +265,8 @@ class Menu(TerminalMenu):
return MenuSelection(type_=MenuSelectionType.Skip) return MenuSelection(type_=MenuSelectionType.Skip)
def run(self) -> MenuSelection: def run(self) -> MenuSelection:
Menu._menu_is_active = True
selection = self._show() selection = self._show()
if selection.type_ == MenuSelectionType.Reset: if selection.type_ == MenuSelectionType.Reset:
@ -277,6 +284,8 @@ class Menu(TerminalMenu):
selection.type_ = MenuSelectionType.Skip selection.type_ = MenuSelectionType.Skip
selection.value = None selection.value = None
Menu._menu_is_active = False
return selection return selection
def set_cursor_pos(self,pos :int): def set_cursor_pos(self,pos :int):

View File

@ -318,9 +318,11 @@ def log(
Journald.log(text, level=level) Journald.log(text, level=level)
# Finally, print the log unless we skipped it based on level. from .menu import Menu
# We use sys.stdout.write()+flush() instead of print() to try and if not Menu.is_menu_active():
# fix issue #94 # Finally, print the log unless we skipped it based on level.
if level != logging.DEBUG or storage.get('arguments', {}).get('verbose', False): # We use sys.stdout.write()+flush() instead of print() to try and
sys.stdout.write(f"{text}\n") # fix issue #94
sys.stdout.flush() if level != logging.DEBUG or storage.get('arguments', {}).get('verbose', False):
sys.stdout.write(f"{text}\n")
sys.stdout.flush()