Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib/hsm
diff options
context:
space:
mode:
Diffstat (limited to 'archinstall/lib/hsm')
-rw-r--r--archinstall/lib/hsm/__init__.py4
-rw-r--r--archinstall/lib/hsm/fido.py57
2 files changed, 61 insertions, 0 deletions
diff --git a/archinstall/lib/hsm/__init__.py b/archinstall/lib/hsm/__init__.py
new file mode 100644
index 00000000..c0888b04
--- /dev/null
+++ b/archinstall/lib/hsm/__init__.py
@@ -0,0 +1,4 @@
+from .fido import (
+ get_fido2_devices,
+ fido2_enroll
+) \ No newline at end of file
diff --git a/archinstall/lib/hsm/fido.py b/archinstall/lib/hsm/fido.py
new file mode 100644
index 00000000..49f36957
--- /dev/null
+++ b/archinstall/lib/hsm/fido.py
@@ -0,0 +1,57 @@
+import typing
+import pathlib
+import getpass
+import logging
+from ..general import SysCommand, SysCommandWorker, clear_vt100_escape_codes
+from ..disk.partition import Partition
+from ..general import log
+
+def get_fido2_devices() -> typing.Dict[str, typing.Dict[str, str]]:
+ """
+ Uses systemd-cryptenroll to list the FIDO2 devices
+ connected that supports FIDO2.
+ Some devices might show up in udevadm as FIDO2 compliant
+ when they are in fact not.
+
+ The drawback of systemd-cryptenroll is that it uses human readable format.
+ That means we get this weird table like structure that is of no use.
+
+ So we'll look for `MANUFACTURER` and `PRODUCT`, we take their index
+ and we split each line based on those positions.
+ """
+ worker = clear_vt100_escape_codes(SysCommand(f"systemd-cryptenroll --fido2-device=list").decode('UTF-8'))
+
+ MANUFACTURER_POS = 0
+ PRODUCT_POS = 0
+ devices = {}
+ for line in worker.split('\r\n'):
+ if '/dev' not in line:
+ MANUFACTURER_POS = line.find('MANUFACTURER')
+ PRODUCT_POS = line.find('PRODUCT')
+ continue
+
+ path = line[:MANUFACTURER_POS].rstrip()
+ manufacturer = line[MANUFACTURER_POS:PRODUCT_POS].rstrip()
+ product = line[PRODUCT_POS:]
+
+ devices[path] = {
+ 'manufacturer' : manufacturer,
+ 'product' : product
+ }
+
+ return devices
+
+def fido2_enroll(hsm_device_path :pathlib.Path, partition :Partition, password :str) -> bool:
+ worker = SysCommandWorker(f"systemd-cryptenroll --fido2-device={hsm_device_path} {partition.real_device}", peak_output=True)
+ pw_inputted = False
+ pin_inputted = False
+ while worker.is_alive():
+ if pw_inputted is False and bytes(f"please enter current passphrase for disk {partition.real_device}", 'UTF-8') in worker._trace_log.lower():
+ worker.write(bytes(password, 'UTF-8'))
+ pw_inputted = True
+
+ elif pin_inputted is False and bytes(f"please enter security token pin", 'UTF-8') in worker._trace_log.lower():
+ worker.write(bytes(getpass.getpass(" "), 'UTF-8'))
+ pin_inputted = True
+
+ log(f"You might need to touch the FIDO2 device to unlock it if no prompt comes up after 3 seconds.", level=logging.INFO, fg="yellow") \ No newline at end of file