From 215198634a682f8f6c9a506adbedce1c5a31b098 Mon Sep 17 00:00:00 2001
From: Timothee 'TTimo' Besset <ttimo@valvesoftware.com>
Date: Tue, 5 Jul 2022 11:40:01 +0200
Subject: [PATCH] refactor for the hackendeck use case

---
 hackendeck/approve-ssh-key         | 32 ++++++++++++++++++++++++
 hackendeck/configure-hackendeck.py | 26 +++++++++----------
 hackendeck/steam-devkit-tool       | 14 +++--------
 src/steamos-devkit-service.py      | 40 ++++++++++--------------------
 4 files changed, 62 insertions(+), 50 deletions(-)
 create mode 100755 hackendeck/approve-ssh-key

diff --git a/hackendeck/approve-ssh-key b/hackendeck/approve-ssh-key
new file mode 100755
index 0000000..6f330b7
--- /dev/null
+++ b/hackendeck/approve-ssh-key
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+# a simplified version of the approve key script, that bypasses the steam client for the hackendeck setup
+
+import sys
+import subprocess
+import json
+import logging
+
+logging.basicConfig(level=logging.INFO, format='%(message)s')
+LOG = logging.getLogger(__name__)
+
+if __name__ == '__main__':
+    request = open(sys.argv[1], 'rt').read()
+    requestIP = 'Unknown'
+    try:
+        requestIP = sys.argv[2]
+    except NameError:
+        LOG.warning('request IP not given as argument to hook')
+        pass
+
+    key_identifier = request.split(' ')[2]
+    prompt = f'Approve pairing request from {requestIP} {key_identifier!r} ?'
+    cmd = ['zenity', '--question', '--text', prompt, '--ok-label', 'Approve', '--cancel-label', 'Deny', '--timeout=10']
+    LOG.info(cmd)
+    cp = subprocess.run(cmd)
+
+    ret = {}
+    if cp.returncode != 0:
+        ret['error'] = 'denied'
+    print(json.dumps({}))
+
+    sys.exit(cp.returncode)
\ No newline at end of file
diff --git a/hackendeck/configure-hackendeck.py b/hackendeck/configure-hackendeck.py
index 801eca9..826eee9 100755
--- a/hackendeck/configure-hackendeck.py
+++ b/hackendeck/configure-hackendeck.py
@@ -15,28 +15,28 @@ if __name__ == '__main__':
 
     hackendeck = ( subprocess.run('grep -e "^ID=manjaro$" /etc/os-release', shell=True).returncode == 0 )
     if not hackendeck:
-        # plz send patches
+        # plz send patches towards support for other distros ..
         logger.info('Only supported on Manjaro - please check documentation')
         sys.exit(1)
 
     logger.info('======== Running hackendeck configuration checks ==========')
+
+    # some gross hack to escape the scout LD_* setup (causes pacman etc. tools to fail)
+    os.environ['LD_LIBRARY_PATH'] = ''
+
     assert os.path.exists(KSSHASKPASS)
     os.environ['SUDO_ASKPASS'] = KSSHASKPASS
-    # this goes pear shaped because of LD_* scout runtime
-    #need_tk = ( subprocess.run('pacman -Q tk', shell=True).returncode != 0 )
-    need_tk = not os.path.exists('/usr/lib/libtk.so')
-    if need_tk:
-        logger.info('Installing Tk library')
-        subprocess.check_call('sudo -A pacman --noconfirm -S tk', shell=True)
-    logger.info('Tk library is installed')
-    need_patch_sshd = ( subprocess.run(f'grep -e "^PubkeyAcceptedAlgorithms" {SSHD_CONFIG}', shell=True).returncode != 0 )
-    if need_patch_sshd:
-        logger.info('Patch sshd for old ssh-rsa hash')
-        subprocess.check_call('sudo -A bash -c \'echo -e "HostkeyAlgorithms +ssh-rsa\nPubkeyAcceptedAlgorithms +ssh-rsa\n" >> /etc/ssh/sshd_config\'', shell=True)
-    logger.info('sshd has been patched for old ssh-rsa hash')
+
     enable_sshd = ( subprocess.run('systemctl status sshd 2>&1 >/dev/null', shell=True).returncode != 0 )
     if enable_sshd:
         logger.info('sshd needs to be enabled')
         subprocess.check_call('sudo -A systemctl enable --now sshd', shell=True)
     logger.info('sshd is enabled')
+
+    # pretty sure those are installed by default, but just in case ..
+    install_packages = ( subprocess.run('pacman -Qi avahi dbus-python zenity >/dev/null', shell=True).returncode != 0 )
+    if install_packages:
+        logger.info('installing packages for the service')
+        subprocess.check_call('sudo -A pacman -S avahi dbus-python zenity', shell=True)
+
     logger.info('======== hackendeck configuration complete ==========')
diff --git a/hackendeck/steam-devkit-tool b/hackendeck/steam-devkit-tool
index 0f81841..6e2ed5c 100755
--- a/hackendeck/steam-devkit-tool
+++ b/hackendeck/steam-devkit-tool
@@ -4,14 +4,8 @@ set -o pipefail
 shopt -s failglob
 set -u
 
-# https://archived.forum.manjaro.org/t/tk-error-application-specific-initialization-failed-unknown-color-name-background/155675/2
-xrdb -load /dev/null
-
-GUI_FOLDER="$(cd $(dirname $0) && echo $PWD)"
-BIN_FOLDER=$(realpath ${GUI_FOLDER}/../bin)
-export PATH="${BIN_FOLDER}:$PATH"
-
-${BIN_FOLDER}/configure-hackendeck.py || exit 1
-
-exec ${GUI_FOLDER}/steam-devkit-gui.pyz
+TOP_FOLDER="$(cd $(dirname $0) && echo $PWD)"
+${TOP_FOLDER}/configure-hackendeck.py || exit 1
+HOOKS_FOLDER=${TOP_FOLDER}/hooks
+exec konsole -e ${TOP_FOLDER}/steamos-devkit-service.py --hooks ${HOOKS_FOLDER}
 
diff --git a/src/steamos-devkit-service.py b/src/steamos-devkit-service.py
index f6e707b..27113e6 100755
--- a/src/steamos-devkit-service.py
+++ b/src/steamos-devkit-service.py
@@ -33,9 +33,9 @@ import socketserver
 import subprocess
 import tempfile
 import urllib.parse
+import argparse
 
 import dbus
-
 import avahi
 
 SERVICE_PORT = 32000
@@ -53,8 +53,6 @@ PROPERTIES = {"txtvers": 1,
               "devkit1": [
                   ENTRY_POINT
               ]}
-HOOK_DIRS = []
-USE_DEFAULT_HOOKS = True
 
 
 def write_file(data: bytes) -> str:
@@ -150,33 +148,11 @@ def find_hook(name: str) -> str:
 
     Return the path to the hook if found. '' if not found
     """
-    # First see if it exists in the given paths.
-    for path in HOOK_DIRS:
-        test_path = os.path.join(path, name)
-        if os.path.exists(test_path) and os.access(test_path, os.X_OK):
-            return test_path
-
-    if not USE_DEFAULT_HOOKS:
-        print(f"Error: Unable to find hook for {name} in hook directories\n")
-        return ''
-
-    test_path = f"/etc/{PACKAGE}/hooks/{name}"
-    if os.path.exists(test_path) and os.access(test_path, os.X_OK):
-        return test_path
-
     test_path = f"{DEVKIT_HOOKS_DIR}/{name}"
     if os.path.exists(test_path) and os.access(test_path, os.X_OK):
         return test_path
 
-    test_path = f"{DEVKIT_HOOKS_DIR}/{name}.sample"
-    if os.path.exists(test_path) and os.access(test_path, os.X_OK):
-        return test_path
-
-    test_path = f"{os.path.dirname(os.path.realpath(__file__))}/../hooks/{name}"
-    if os.path.exists(test_path) and os.access(test_path, os.X_OK):
-        return test_path
-
-    print(f"Error:: Unable to find hook for {name} in /etc/{PACKAGE}/hooks or {DEVKIT_HOOKS_DIR}")
+    print(f"Error:: Unable to find hook for {name}")
     return ''
 
 
@@ -367,7 +343,7 @@ class DevkitService:
                     DEVICE_USERS = users["ShellUsers"]
             else:
                 username = getpass.getuser()
-                print("Username: {username}")
+                print(f'Username: {username}')
                 DEVICE_USERS = []
                 DEVICE_USERS.append(username)
 
@@ -428,6 +404,16 @@ class DevkitService:
 
 
 if __name__ == "__main__":
+    print(f'==========================')
+    print(f'  SteamOS Devkit Service')
+    print(f'==========================')
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--hooks', required=False, action='store', help='hooks directory')
+    conf = parser.parse_args()
+
+    if conf.hooks is not None:
+        DEVKIT_HOOKS_DIR = conf.hooks
+
     service = DevkitService()
 
     service.publish()
-- 
GitLab