|
|
@ -2,6 +2,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
#TODO: |
|
|
|
#TODO: |
|
|
|
# - resolve exploit where key is plugged in and out quickly, resulting in an unlocked state |
|
|
|
# - resolve exploit where key is plugged in and out quickly, resulting in an unlocked state |
|
|
|
|
|
|
|
# - Add async scheduler that runs update_lock_state() every 1 minute or so |
|
|
|
|
|
|
|
|
|
|
|
import os |
|
|
|
import os |
|
|
|
import sys |
|
|
|
import sys |
|
|
@ -48,6 +49,12 @@ def execute(command: str, shell_on: bool = False, background: bool = False): |
|
|
|
logger.error(err.decode('utf-8').rstrip()) |
|
|
|
logger.error(err.decode('utf-8').rstrip()) |
|
|
|
return '' if out == b'' else out.decode('utf-8') |
|
|
|
return '' if out == b'' else out.decode('utf-8') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def screensaver_running(): |
|
|
|
|
|
|
|
graphic_program_instances = execute(f"{script_dir}/kill_screensaver_graphic_program.sh -d | grep graphic_processes | wc -l", shell_on=True) |
|
|
|
|
|
|
|
if int(graphic_program_instances) > 0: |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
def lock_screen(): |
|
|
|
def lock_screen(): |
|
|
|
if args.dummy : |
|
|
|
if args.dummy : |
|
|
|
return |
|
|
|
return |
|
|
@ -59,6 +66,7 @@ def lock_screen(): |
|
|
|
def unlock_screen(): |
|
|
|
def unlock_screen(): |
|
|
|
if args.dummy : |
|
|
|
if args.dummy : |
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
logger.info('xscreen process to be killed:') |
|
|
|
logger.info('xscreen process to be killed:') |
|
|
|
xscreensaver_pid = execute(r'ps -A | grep -oPm 1 "\d{2,}(?=\s.+xscreensaver)" || echo null', |
|
|
|
xscreensaver_pid = execute(r'ps -A | grep -oPm 1 "\d{2,}(?=\s.+xscreensaver)" || echo null', |
|
|
|
shell_on=True) |
|
|
|
shell_on=True) |
|
|
@ -83,22 +91,30 @@ def get_yubikey_serials() -> int: |
|
|
|
except yubico.yubikey.YubiKeyError: |
|
|
|
except yubico.yubikey.YubiKeyError: |
|
|
|
pass |
|
|
|
pass |
|
|
|
except USBError as error: |
|
|
|
except USBError as error: |
|
|
|
logger.error('get_yubikey_serials() threw: %s', str(error)) |
|
|
|
logger.info('get_yubikey_serials() threw: %s', str(error)) |
|
|
|
|
|
|
|
|
|
|
|
if not serials: |
|
|
|
if not serials: |
|
|
|
logger.info('no yubikey connected') |
|
|
|
logger.info('no yubikey connected') |
|
|
|
|
|
|
|
|
|
|
|
return serials |
|
|
|
return serials |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_lock_state(): |
|
|
|
|
|
|
|
if any(serial in yubikey_serials for serial in get_yubikey_serials()): |
|
|
|
|
|
|
|
if screensaver_running(): |
|
|
|
|
|
|
|
logger.debug('screen will be unlocked') |
|
|
|
|
|
|
|
unlock_screen() |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
if not screensaver_running(): |
|
|
|
|
|
|
|
logger.debug('screen will be locked') |
|
|
|
|
|
|
|
lock_screen() |
|
|
|
|
|
|
|
|
|
|
|
def device_added(device, last_yubikey_time): |
|
|
|
def device_added(device, last_yubikey_time): |
|
|
|
logger.debug('device connected: %s', device.sys_name) |
|
|
|
logger.debug('device connected: %s', device.sys_name) |
|
|
|
if (datetime.now() - last_yubikey_time).total_seconds() > 0.3 : |
|
|
|
if (datetime.now() - last_yubikey_time).total_seconds() > 0.3 : |
|
|
|
# This is not nice, yubikey call can cause key to reconnect. |
|
|
|
# This is not nice, yubikey call can cause key to reconnect. |
|
|
|
# This cooldown prevents endless reconnect loops |
|
|
|
# This cooldown prevents endless reconnect loops |
|
|
|
|
|
|
|
|
|
|
|
if any(serial in yubikey_serials for serial in get_yubikey_serials()): |
|
|
|
update_lock_state() |
|
|
|
logger.debug('screen will be unlocked') |
|
|
|
|
|
|
|
unlock_screen() |
|
|
|
|
|
|
|
return datetime.now() |
|
|
|
return datetime.now() |
|
|
|
return last_yubikey_time |
|
|
|
return last_yubikey_time |
|
|
|
|
|
|
|
|
|
|
@ -108,9 +124,7 @@ def device_removed(device: pyudev.Device, last_yubikey_time): |
|
|
|
# This is not nice, yubikey call can cause key to reconnect. |
|
|
|
# This is not nice, yubikey call can cause key to reconnect. |
|
|
|
# This cooldown prevents endless reconnect loops |
|
|
|
# This cooldown prevents endless reconnect loops |
|
|
|
|
|
|
|
|
|
|
|
if not any(serial in yubikey_serials for serial in get_yubikey_serials()): |
|
|
|
update_lock_state() |
|
|
|
logger.debug('screen will be locked') |
|
|
|
|
|
|
|
lock_screen() |
|
|
|
|
|
|
|
return datetime.now() |
|
|
|
return datetime.now() |
|
|
|
return last_yubikey_time |
|
|
|
return last_yubikey_time |
|
|
|
|
|
|
|
|
|
|
@ -123,7 +137,9 @@ def get_args(): |
|
|
|
parser.add_argument('-v', '--verbose', action='store_true', help='increase output verbosity') |
|
|
|
parser.add_argument('-v', '--verbose', action='store_true', help='increase output verbosity') |
|
|
|
return parser.parse_args() |
|
|
|
return parser.parse_args() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def daemon(monitor): |
|
|
|
def daemon(monitor): |
|
|
|
|
|
|
|
|
|
|
|
last_yubikey_time = datetime.fromtimestamp(0) |
|
|
|
last_yubikey_time = datetime.fromtimestamp(0) |
|
|
|
lastdevice = 'hidraw-2' |
|
|
|
lastdevice = 'hidraw-2' |
|
|
|
|
|
|
|
|
|
|
@ -159,9 +175,7 @@ if __name__ == "__main__": |
|
|
|
execute('DISPLAY=:0 xscreensaver -no-splash&', shell_on=True, background = True) |
|
|
|
execute('DISPLAY=:0 xscreensaver -no-splash&', shell_on=True, background = True) |
|
|
|
|
|
|
|
|
|
|
|
# Lock the machine if no key is inserted when the script is started |
|
|
|
# Lock the machine if no key is inserted when the script is started |
|
|
|
if not any(serial in yubikey_serials for serial in get_yubikey_serials()): |
|
|
|
update_lock_state() |
|
|
|
logger.debug('screen will be locked') |
|
|
|
|
|
|
|
lock_screen() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
daemon(get_hid_event_monitor()) |
|
|
|
daemon(get_hid_event_monitor()) |
|
|
|
|
|
|
|
|
|
|
|