Add system and control scripts for Raspberry Pi OS

pios
Andri Yngvason 2023-12-17 14:06:03 +00:00
parent 0859e235c0
commit 6975b25f00
12 changed files with 244 additions and 1 deletions

2
debian/control vendored
View File

@ -30,7 +30,7 @@ Vcs-Browser: https://github.com/any1/wayvnc
Package: wayvnc
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends},
Depends: ${misc:Depends}, ${shlibs:Depends}, python3
Description: VNC server for wlroots-based Wayland compositors
It attaches to a running Wayland session, creates virtual input devices, and
exposes a single display via the RFB protocol. The Wayland session may be a

1
debian/wayvnc.install vendored 100644
View File

@ -0,0 +1 @@
pios-control/* /

31
debian/wayvnc.postinst vendored 100755
View File

@ -0,0 +1,31 @@
#!/bin/sh
set -e
configure_wayvnc()
{
systemd-sysusers ${DPKG_ROOT:+--root="$DPKG_ROOT"} vnc.conf
systemctl --system daemon-reload >/dev/null || true
deb-systemd-invoke enable 'wayvnc-control.service' >/dev/null || true
# If wayvnc was previously configured using xdg-autostart, we want to
# enable it; otherwise, leave it disabled.
if [ -e /etc/xdg/autostart/wayvnc.desktop ]; then
rm -f /etc/xdg/autostart/wayvnc.desktop
deb-systemd-invoke enable 'wayvnc.service' >/dev/null || true
fi
deb-systemd-invoke try-restart 'wayvnc.service' >/dev/null || true
}
case "$1" in
configure)
configure_wayvnc
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinstall called with unknown argument \`$1'" >&2
exit 1
;;
esac

14
debian/wayvnc.postrm vendored 100755
View File

@ -0,0 +1,14 @@
#!/bin/sh
set -e
case "$1" in
remove)
systemctl --system daemon-reload >/dev/null || true
;;
purge)
rm -rf /etc/wayvnc
;;
*)
;;
esac

View File

@ -0,0 +1,7 @@
use_relative_paths=true
address=::
enable_auth=true
enable_pam=true
private_key_file=tls_key.pem
certificate_file=tls_cert.pem
rsa_private_key_file=rsa_key.pem

View File

@ -0,0 +1,13 @@
[Unit]
Description=VNC Control Service
After=wayvnc.service
BindsTo=wayvnc.service
ConditionPathExists=/etc/wayvnc/config
[Service]
Type=simple
ExecStart=/usr/sbin/wayvnc-control.py
Restart=always
[Install]
WantedBy=wayvnc.service

View File

@ -0,0 +1,9 @@
[Unit]
Description=WayVNC Key Generation
ConditionPathExists=|!/etc/wayvnc/rsa_key.pem
ConditionPathExists=|!/etc/wayvnc/tls_key.pem
ConditionPathExists=|!/etc/wayvnc/tls_cert.pem
[Service]
ExecStart=/usr/sbin/wayvnc-generate-keys.sh
Type=oneshot

View File

@ -0,0 +1,17 @@
[Unit]
Description=VNC Server
Documentation=man:wayvnc
After=network.target wayvnc-generate-keys.service
Requires=wayvnc-generate-keys.service
ConditionPathExists=/etc/wayvnc/config
[Service]
ExecStart=/bin/sh /usr/sbin/wayvnc-run.sh
Type=notify
NotifyAccess=all
Restart=always
User=vnc
KillSignal=INT
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,2 @@
u vnc - "vnc" /nonexistent
m vnc shadow

View File

@ -0,0 +1,92 @@
#!/usr/bin/env python
import asyncio
import json
import re
import os
import glob
from pathlib import Path
class Program:
command_seq = 0
reader = None
writer = None
read_buffer = ""
message_queue = asyncio.Queue()
reply_queue = asyncio.Queue()
decoder = json.JSONDecoder()
tasks = []
async def read_message(self):
while True:
try:
result, index = self.decoder.raw_decode(self.read_buffer)
self.read_buffer = self.read_buffer[index:].lstrip()
return result
except json.JSONDecodeError:
data = await self.reader.read(4096)
self.read_buffer += data.decode('utf-8')
async def send_command(self, method, params = None):
cmd = {
"method": method,
"id": self.command_seq,
}
if not params is None:
cmd['params'] = params
self.command_seq += 1
self.writer.write(json.dumps(cmd).encode())
await self.writer.drain()
reply = await self.reply_queue.get()
self.reply_queue.task_done()
return reply['code'] == 0
async def attach(self, display):
# TODO: It would be better to pass the socket on to wayvnc as a file descriptor
proc = await asyncio.create_subprocess_shell('setfacl -m "u:vnc:rwx" {} {}'.format(Path(display).parent, display))
await proc.wait()
return await self.send_command('attach', {'display': display})
async def attach_any(self):
for path in glob.iglob('/run/user/*/wayland-*'):
if path.endswith('.lock'):
continue
if await self.attach(path):
return True
return False
async def attach_any_with_retry(self):
while not await self.attach_any():
await asyncio.sleep(1.0)
async def process_message(self, message):
method = message['method']
if (method == 'detached'):
await self.attach_any_with_retry()
async def message_processor(self):
while True:
message = await self.read_message()
if 'method' in message:
await self.message_queue.put(message)
elif 'code' in message:
await self.reply_queue.put(message)
async def main(self):
self.reader, self.writer = await asyncio.open_unix_connection("/tmp/wayvnc/wayvncctl.sock")
self.tasks.append(asyncio.create_task(self.message_processor()))
await self.attach_any_with_retry()
await self.send_command("event-receive")
while True:
message = await self.message_queue.get()
await self.process_message(message)
prog = Program()
asyncio.run(prog.main())

View File

@ -0,0 +1,34 @@
#!/bin/sh
WAYVNC_CONFIG_PATH=/etc/wayvnc
generate_rsa_key()
{
echo "Generating RSA key..."
KEY_FILE="$WAYVNC_CONFIG_PATH/rsa_key.pem"
ssh-keygen -m pem -f "$KEY_FILE" -t rsa -N "" >/dev/null
rm -f "$KEY_FILE.pub"
chown root:vnc "$KEY_FILE"
chmod 640 "$KEY_FILE"
echo "Done"
}
generate_tls_creds()
{
echo "Generating TLS Credentials..."
KEY_FILE="$WAYVNC_CONFIG_PATH/tls_key.pem"
CERT_FILE="$WAYVNC_CONFIG_PATH/tls_cert.pem"
HOSTNAME=$(cat /etc/hostname)
IP=$(ip a | awk '$1=="inet" && $2 != "127.0.0.1/8" {split($2, a, "/"); print a[1]}')
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
-keyout "$KEY_FILE" -out "$CERT_FILE" -subj /CN=$HOSTNAME \
-addext subjectAltName=DNS:localhost,DNS:$HOSTNAME,IP:$IP 2>/dev/null
chown root:vnc "$KEY_FILE" "$CERT_FILE"
chmod 640 "$KEY_FILE" "$CERT_FILE"
echo "Done"
}
test -e "$WAYVNC_CONFIG_PATH" || mkdir -p "$WAYVNC_CONFIG_PATH"
test -e "$WAYVNC_CONFIG_PATH/rsa_key.pem" || generate_rsa_key
test -e "$WAYVNC_CONFIG_PATH/tls_key.pem" -a \
-e "$WAYVNC_CONFIG_PATH/tls_cert.pem" || generate_tls_creds

View File

@ -0,0 +1,23 @@
#!/bin/sh
. /etc/default/keyboard
export XDG_RUNTIME_DIR=/tmp/wayvnc
mkdir -p "$XDG_RUNTIME_DIR"
export XKB_DEFAULT_MODEL="$XKBMODEL"
export XKB_DEFAULT_LAYOUT="$XKBLAYOUT"
SELF_PID=$$
{
while ! wayvncctl --socket=/tmp/wayvnc/wayvncctl.sock version >/dev/null 2>&1; do
sleep 0.1
done
systemd-notify --ready --pid=$SELF_PID
} &
wayvnc --render-cursor \
--detached \
--config /etc/wayvnc/config \
--socket /tmp/wayvnc/wayvncctl.sock