random-scripts/usbguard-menu.py

94 lines
2.6 KiB
Python
Executable File

#!/usr/bin/env python
from enum import Enum
import subprocess
import shlex
class DeviceMode(Enum):
DENY = 0
ALLOW = 1
class Device:
def __init__(self, mode, id, name, hash):
self.mode = mode
self.id = id
self.name = name
self.hash = hash
def from_output_line(line):
tokens = shlex.split(line, False, True)
mode = DeviceMode.DENY
id = None
name = None
hash = None
for i, token in enumerate(tokens):
if i == len(tokens) - 1:
next = None
else:
next = tokens[i + 1]
match token:
case 'allow':
mode = DeviceMode.ALLOW
case 'id':
id = next
case 'name':
name = next
case 'hash':
hash = next
return Device(mode, id, name, hash)
def __str__(self):
match self.mode:
case DeviceMode.ALLOW:
mode = "Allowed"
case _:
mode = "Denied"
if len(self.name) == 0:
name = "<no name>"
else:
name = self.name
return f'{self.id}: {name} ({mode}, Hash: {self.hash})'
def run_fuzzel(entries, prompt=None):
cmd = ["fuzzel", "-d", "--index"]
if prompt is not None:
cmd.append(f'--prompt={prompt}')
proc = subprocess.run(cmd,
input='\n'.join(str(e) for e in entries),
capture_output=True,
text=True,
shell=False)
if proc.returncode != 0:
return None
return entries[int(proc.stdout)]
devices = []
proc = subprocess.run(["usbguard", "list-devices"],
capture_output=True, text=True, check=True)
for line in proc.stdout.splitlines():
devices.append(Device.from_output_line(line))
device = run_fuzzel(devices)
if device is None:
exit()
action = run_fuzzel(['Allow', 'Deny', 'Reject'],
device.name + ' > ')
if action is None:
exit()
match action:
case 'Allow':
subprocess.check_output(['usbguard',
'allow-device',
device.id], shell=False)
case 'Reject':
subprocess.check_output(['usbguard',
'reject-device',
device.id], shell=False)
case _:
subprocess.check_output(['usbguard',
'block-device',
device.id], shell=False)