Add system and control scripts for Raspberry Pi OS
parent
0859e235c0
commit
6975b25f00
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
pios-control/* /
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
u vnc - "vnc" /nonexistent
|
||||
m vnc shadow
|
|
@ -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())
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue