import base64 import hashlib import io from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.serialization import load_ssh_public_key from flask import Blueprint, redirect, render_template, request, url_for, Markup, flash from forms import AddSSHUser from api import Client from utils import admin_required remote_page = Blueprint("remote", __name__, url_prefix="/remote") def ssh_fingerprint(key): fp = hashlib.md5(base64.b64decode(key)).hexdigest() return ":".join(a + b for a, b in zip(fp[::2], fp[1::2])) @remote_page.route("/stop") @admin_required def stop(): c = Client() session_id = request.args.get("session") c.jellyfin.stop_session(session_id) return redirect(url_for("remote.index")) @remote_page.route("/") @admin_required def index(): c = Client() res = c.ssh.get("/data/.ssh/authorized_keys", io.BytesIO()) res.local.seek(0) ssh_keys = [] for key in str(res.local.read(), "utf8").splitlines(): disabled = False if key.startswith("#"): key = key.lstrip("#").lstrip() disabled = True load_ssh_public_key(bytes(key, "utf8")) key_type, key, name = key.split(None, 2) ssh_keys.append( { "disabled": disabled, "type": key_type, "key": key, "fingerprint": ssh_fingerprint(key), "name": name, } ) key = request.args.get("key") enabled = request.args.get("enabled") if not (key is None or enabled is None): key_file = [] for ssh_key in ssh_keys: if ssh_key["key"] == key: ssh_key["disabled"] = enabled == "False" if ssh_key["disabled"]: key_file.append("#{type} {key} {name}".format(**ssh_key)) else: key_file.append("{type} {key} {name}".format(**ssh_key)) buf = io.BytesIO(bytes("\n".join(key_file), "utf8")) c.ssh.put(buf, "/data/.ssh/authorized_keys", preserve_mode=False) return redirect(url_for("remote")) jellyfin = { "users": c.jellyfin.get_users(), "sessions": c.jellyfin.sessions(), "info": c.jellyfin.system_info(), } return render_template( "remote/index.html", ssh=ssh_keys, jellyfin=jellyfin) @remote_page.route("/add", methods=["GET", "POST"]) @admin_required def add(): form = AddSSHUser() c = Client() if form.validate_on_submit(): key = load_ssh_public_key(bytes(form.data["ssh_key"], "utf8")) rawKeyData = key.public_bytes( encoding=serialization.Encoding.OpenSSH, format=serialization.PublicFormat.OpenSSH, ) passwd = c.add_user(form.data["name"], str(rawKeyData, "utf8")) flash( Markup( "".join( [ f"

Name: {form.data['name']}

", f"

PW: {passwd}

", f"

FP: {ssh_fingerprint(rawKeyData.split()[1])}

", ]))) return render_template("remote/add.html", form=form)