hls-livecam-server
The .install script modifies system services and sudoers files during setup, but only as part of expected post-install configuration initiated by the user via sudo hls-livecam-setup; it does not perform unauthorized privileged actions or self-update in a dangerous way.
Triggered rules
llm_review
The static rules flagged this MEDIUM, but an AI model (qwen/qwen3-235b-a22b-2507) reviewed the full PKGBUILD and judged it LOW (confidence 95%): The .install script modifies system services and sudoers files during setup, but only as part of expected post-install configuration initiated by the user via sudo hls-livecam-setup; it does not perform unauthorized privileged actions or self-update in a dangerous way.
1 higher static finding superseded - not the current verdict (shown for transparency)
privileged_install
The package grants elevated privileges or installs an update path outside pacman: a /etc/sudoers.d rule (often passwordless), a setuid/setgid binary, or a self-update script/service that can fetch and run future code with no checksum verification. The initial install may be verified, but the ongoing privilege + update surface is a real supply-chain / privilege-escalation risk.
-
.install:71
rm -f /etc/sudoers.d/hls-livecam-dark -
.install:72
rm -f /etc/sudoers.d/hls-livecam-services -
.install:73
rm -f /etc/sudoers.d/camdash-smart
PKGBUILD
# Maintainer: Ron <thefangeddeity>
pkgname=hls-livecam-server
pkgver=7.0.0
pkgrel=1
pkgdesc="Stream a USB webcam via HLS using MediaMTX and ffmpeg, with browser viewer, camdash monitor, and family presence features"
arch=('any')
url="https://github.com/thefangeddeity/hls-livecam-server"
license=('GPL-3.0-or-later')
depends=('ffmpeg' 'nginx' 'python' 'python-psutil' 'python-flask' 'python-pillow' 'python-numpy' 'python-opencv' 'python-pyfakewebcam' 'pyside6' 'v4l2loopback-dkms' 'smartmontools' 'v4l-utils' 'wget' 'ttf-dejavu')
install=hls-livecam-server.install
source=("$pkgname-$pkgver.tar.gz::https://github.com/thefangeddeity/hls-livecam-server/archive/refs/tags/v$pkgver.tar.gz"
"hls-livecam-server.install")
sha256sums=('b513b7a101a5e1bc5a9acc2919fbbe188f4d788a31fe1265f2e771f037b9bd0e'
'SKIP')
package() {
cd "$pkgname-$pkgver"
# ── Executables ──────────────────────────────────────────────────────────
install -Dm755 pkg/usr/share/hls-livecam-server/hls-livecam-setup-arch \
"$pkgdir/usr/local/bin/hls-livecam-setup"
install -Dm755 pkg/usr/local/bin/camdash "$pkgdir/usr/local/bin/camdash"
install -Dm755 pkg/usr/local/bin/camstack "$pkgdir/usr/local/bin/camstack"
install -Dm755 pkg/usr/local/bin/hls-livecam-repair "$pkgdir/usr/local/bin/hls-livecam-repair"
install -Dm755 pkg/usr/local/bin/hls-livecam-dark "$pkgdir/usr/local/bin/hls-livecam-dark"
install -Dm755 pkg/usr/local/bin/broadcast-api "$pkgdir/usr/local/bin/broadcast-api"
install -Dm755 camdash-gui "$pkgdir/usr/local/bin/camdash-gui"
# ── Operator GUI ─────────────────────────────────────────────────────────
# gui/ lives at the repo root rather than under pkg/, deliberately: pkg/ is
# packaged wholesale into the .deb, and PySide6 is not available in Debian
# bookworm (the pyside6 split packages start at trixie), nor is there a
# display on the headless Debian node. Arch installs it from here; the deb
# simply never sees it.
for f in __init__ app probes tokens video widgets; do
install -Dm644 "gui/$f.py" "$pkgdir/usr/share/hls-livecam-server/gui/$f.py"
done
install -Dm644 gui/assets/icon_1024.png \
"$pkgdir/usr/share/hls-livecam-server/gui/assets/icon_1024.png"
# The desktop entry is registered by hls-livecam-setup, which also prepares
# the per-user config dir the GUI persists window geometry into; shipping it
# to share/ keeps setup's copy source in the package.
install -Dm644 camdash-gui.desktop \
"$pkgdir/usr/share/hls-livecam-server/camdash-gui.desktop"
# ── Shared data ──────────────────────────────────────────────────────────
install -Dm755 pkg/usr/share/hls-livecam-server/camdash \
"$pkgdir/usr/share/hls-livecam-server/camdash"
install -Dm755 pkg/usr/share/hls-livecam-server/camstack \
"$pkgdir/usr/share/hls-livecam-server/camstack"
install -Dm755 pkg/usr/share/hls-livecam-server/hls-livecam-setup-arch \
"$pkgdir/usr/share/hls-livecam-server/hls-livecam-setup"
install -Dm755 pkg/usr/share/hls-livecam-server/hls-livecam-repair \
"$pkgdir/usr/share/hls-livecam-server/hls-livecam-repair"
install -Dm644 pkg/usr/share/hls-livecam-server/block_art.py \
"$pkgdir/usr/share/hls-livecam-server/block_art.py"
install -Dm644 pkg/usr/share/hls-livecam-server/cv_processor.py \
"$pkgdir/usr/share/hls-livecam-server/cv_processor.py"
install -Dm644 pkg/usr/share/hls-livecam-server/cv_detect.py \
"$pkgdir/usr/share/hls-livecam-server/cv_detect.py"
install -Dm644 pkg/usr/share/hls-livecam-server/cv_notify.py \
"$pkgdir/usr/share/hls-livecam-server/cv_notify.py"
install -Dm644 pkg/usr/share/hls-livecam-server/cv_scene.py \
"$pkgdir/usr/share/hls-livecam-server/cv_scene.py"
# cv_persist and cv_occupancy are imported behind try/except in
# cv_processor -- absent, they disable themselves and say nothing. That
# is the right runtime behaviour and exactly why leaving them out of the
# package was invisible: an Arch install simply had no persistence and
# no occupancy, with nothing in the log to suggest either had been asked
# for. Optional at import time, mandatory in the payload.
install -Dm644 pkg/usr/share/hls-livecam-server/cv_persist.py \
"$pkgdir/usr/share/hls-livecam-server/cv_persist.py"
install -Dm644 pkg/usr/share/hls-livecam-server/cv_occupancy.py \
"$pkgdir/usr/share/hls-livecam-server/cv_occupancy.py"
# The viewer's header asks for /brand.png. Ship the source of it here;
# hls-livecam-setup and post_upgrade put it in the web root.
install -Dm644 pkg/usr/share/hls-livecam-server/brand.png \
"$pkgdir/usr/share/hls-livecam-server/brand.png"
install -Dm755 pkg/usr/share/hls-livecam-server/cv_scene_register.py \
"$pkgdir/usr/share/hls-livecam-server/cv_scene_register.py"
install -Dm644 pkg/usr/share/hls-livecam-server/index.html \
"$pkgdir/usr/share/hls-livecam-server/index.html"
# The viewer loads the HLS player from /vendor/hls.min.js, same-origin,
# deliberately not from cdnjs (a phone on a captive/filtered network got
# a blank viewer otherwise -- see index.html's own comment on the
# <script> tag). Missed when vendor/ was added: without this file a
# fresh Arch install left Chrome/Firefox viewers silently broken (no
# crash -- the page guards every Hls reference -- just no video),
# exactly the failure class the vendoring was meant to prevent.
install -Dm644 pkg/usr/share/hls-livecam-server/vendor/hls.min.js \
"$pkgdir/usr/share/hls-livecam-server/vendor/hls.min.js"
# VERSION and PRODUCT are read by broadcast-api at /api/info time. They
# were never installed here, so an Arch node reported an empty version
# tag in its header and fell back to the built-in product identity --
# correct for this fleet by luck, wrong for anyone forking it. Shipping
# them makes the header true on a fresh install rather than only on a
# node someone hand-copied them to. A forked node overrides PRODUCT in
# /etc/hls-livecam/PRODUCT, which no installer touches.
install -Dm644 pkg/usr/share/hls-livecam-server/VERSION \
"$pkgdir/usr/share/hls-livecam-server/VERSION"
install -Dm644 pkg/usr/share/hls-livecam-server/PRODUCT \
"$pkgdir/usr/share/hls-livecam-server/PRODUCT"
install -Dm644 pkg/usr/share/hls-livecam-server/cams/cams.html \
"$pkgdir/usr/share/hls-livecam-server/cams/cams.html"
install -Dm644 pkg/usr/share/hls-livecam-server/ffmpeg-cam.service \
"$pkgdir/usr/share/hls-livecam-server/ffmpeg-cam.service"
# NOTE: var/www/hls-livecam/index.html is NOT installed here.
# hls-livecam-setup populates /var/www/hls-livecam/ at configure time,
# substituting @HOSTNAME@ into share/index.html. Installing a pre-baked
# file here would overwrite it with the wrong hostname on every upgrade.
# ── Systemd services ─────────────────────────────────────────────────────
# Arch convention: vendor units go to /usr/lib/systemd/system/
install -Dm644 pkg/usr/share/hls-livecam-server/broadcast-api-arch.service \
"$pkgdir/usr/lib/systemd/system/broadcast-api.service"
install -Dm644 pkg/etc/systemd/system/ffmpeg-cam-dark.service \
"$pkgdir/usr/lib/systemd/system/ffmpeg-cam-dark.service"
install -Dm644 pkg/usr/lib/systemd/system/ffmpeg-cam.service \
"$pkgdir/usr/lib/systemd/system/ffmpeg-cam.service"
# ── tmpfiles.d ───────────────────────────────────────────────────────────
install -Dm644 pkg/usr/lib/tmpfiles.d/hls-livecam.conf \
"$pkgdir/usr/lib/tmpfiles.d/hls-livecam.conf"
# ── nginx ────────────────────────────────────────────────────────────────
install -Dm644 pkg/etc/nginx/conf.d/hls-livecam.conf "$pkgdir/etc/nginx/conf.d/hls-livecam.conf"
# ── Sudoers ───────────────────────────────────────────────────────────────
# All sudoers.d entries (hls-livecam-dark, hls-livecam-services, camdash-smart)
# are written dynamically by hls-livecam-setup at configure time — setup owns
# sudoers, package() does not ship a static copy (v5.2.1: the shipped copy was
# a stale fossil that setup immediately overwrites on first run anyway).
}
Changes since previous scan
--- PKGBUILD @ 2026-09-10 00:22+++ PKGBUILD @ 2026-09-17 00:27@@ -1,6 +1,6 @@ # Maintainer: Ron <thefangeddeity> pkgname=hls-livecam-server-pkgver=6.0.6+pkgver=7.0.0 pkgrel=1 pkgdesc="Stream a USB webcam via HLS using MediaMTX and ffmpeg, with browser viewer, camdash monitor, and family presence features" arch=('any')@@ -10,7 +10,7 @@ install=hls-livecam-server.install source=("$pkgname-$pkgver.tar.gz::https://github.com/thefangeddeity/hls-livecam-server/archive/refs/tags/v$pkgver.tar.gz" "hls-livecam-server.install")-sha256sums=('3b1e682c4f9e933d84895929646b64812f0171d0cb93b64f676d23d29d4c722f'+sha256sums=('b513b7a101a5e1bc5a9acc2919fbbe188f4d788a31fe1265f2e771f037b9bd0e' 'SKIP') package() {@@ -80,6 +80,15 @@ "$pkgdir/usr/share/hls-livecam-server/cv_scene_register.py" install -Dm644 pkg/usr/share/hls-livecam-server/index.html \ "$pkgdir/usr/share/hls-livecam-server/index.html"+ # The viewer loads the HLS player from /vendor/hls.min.js, same-origin,+ # deliberately not from cdnjs (a phone on a captive/filtered network got+ # a blank viewer otherwise -- see index.html's own comment on the+ # <script> tag). Missed when vendor/ was added: without this file a+ # fresh Arch install left Chrome/Firefox viewers silently broken (no+ # crash -- the page guards every Hls reference -- just no video),+ # exactly the failure class the vendoring was meant to prevent.+ install -Dm644 pkg/usr/share/hls-livecam-server/vendor/hls.min.js \+ "$pkgdir/usr/share/hls-livecam-server/vendor/hls.min.js" # VERSION and PRODUCT are read by broadcast-api at /api/info time. They # were never installed here, so an Arch node reported an empty version # tag in its header and fell back to the built-in product identity --Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-09-17 00:27:14 | Low | 2 |
| 2026-09-16 00:03:17 | Low | 2 |
| 2026-09-15 00:25:31 | Low | 2 |
| 2026-09-14 00:27:57 | Low | 2 |
| 2026-09-13 00:19:54 | Low | 2 |
| 2026-09-12 00:25:17 | Low | 2 |
| 2026-09-11 00:19:22 | Low | 2 |
| 2026-09-10 23:21:28 | Medium | 1 |
| 2026-09-10 00:22:44 | Low | 2 |
| 2026-09-09 00:04:09 | Low | 2 |
| 2026-09-08 00:18:08 | Low | 2 |
| 2026-09-07 00:30:15 | Low | 2 |
| 2026-09-06 00:17:06 | Low | 2 |
| 2026-09-05 00:16:27 | Low | 2 |
| 2026-09-04 00:03:13 | Low | 2 |
| 2026-09-03 00:15:47 | Low | 2 |
| 2026-09-02 00:02:31 | Low | 2 |
| 2026-09-01 00:11:19 | Low | 2 |
| 2026-08-31 00:19:57 | Low | 2 |
| 2026-08-30 00:04:14 | Low | 2 |