GithubHelp home page GithubHelp logo

elliotkillick / qubes-video-companion Goto Github PK

View Code? Open in Web Editor NEW
51.0 8.0 14.0 397 KB

Securely stream webcams and share screens across virtual machines. Project moved: https://github.com/QubesOS/qubes-video-companion

License: MIT License

Makefile 8.01% Shell 34.57% HTML 2.10% Python 55.32%
qubes-os qubes webcam virtual-machine security video airgap screensharing streaming

qubes-video-companion's Introduction

Qubes Video Companion

Securely stream webcams and share screens across virtual machines

About

Qubes Video Companion is a tool for securely streaming webcams and sharing screens across virtual machines.

It accomplishes this by creating a uni-directional flow of raw video that is passed from one virtual machine to another through file descriptors thereby allowing both machines to be completely air-gapped with no networking stacks exposed. This design makes the side of the video sending virtual machine 100% immune to attack and only leaves a very small attack surface on the side of the video receiving virtual machine.

The project emphasizes correctness and security all the while also sporting superb performance by maintaining a small footprint of the available computational resources and low latency even at Full HD and greater resolutions at 30 or more frames per second.

Installation

WIP: Currently in the process of being streamlined as part of core Qubes OS

For testers (thank you for your help!), please use the build scripts in the build directory of this repo to build the required Qubes Video Companion package(s). Install them in sys-usb and any other AppVM for receiving the video. Also, ensure that at minimum in the Qubes RPC policies in qubes-rpc/policies are installed into Dom0 at /etc/qubes-rpc/policy.

Qubes Video Companion is available for installation on Qubes OS in packaged form for both Fedora (.rpm) and Debian (.deb). To get it, simply install the qubes-video-companion package as shown below!

Run the following commands in Dom0 (AdminVM)

sudo qubes-dom0-update qubes-video-companion

Run the following commands in a TemplateVM or AppVM

Fedora

sudo dnf install qubes-video-companion

Debian

sudo apt update && sudo apt install qubes-video-companion

Usage

Webcam

Simply run the following command in the virtual machine of the webcam stream recipient:

qubes-video-companion webcam

A secure confirmation dialog will appear asking where the webcam stream is to be sourced from. If the webcam device is attached to sys-usb then select that qube as the target, if instead the webcam is attached to dom0 then select that as the target. Afterwards, confirm the operation by clicking OK.

Screen Sharing

Simply run the following command in the virtual machine of the screen sharing recipient:

qubes-video-companion screenshare

A secure confirmation dialog will appear asking where the screen to share is to be sourced from. Select any qube as the target screen, this could be a regular unprivileged qube such as personal or a DisposableVM, or the ultimately trusted dom0 (caution is advised to avoid information disclosure. Afterwards, confirm the operation by clicking OK.

Note that confirmation isn't required when a VM wants to view the screen of a DisposableVM it launched itself because the parent VM already has full control over the DisposableVM.

Preview

At this point, install and open an application such as Cheese (packaged as cheese) to preview the webcam or screen shared video stream. You're all set!

Security

Here is a review of the security concerns webcams entail that Qubes users either no longer have to worry about or have been greatly mitigated thanks to Qubes Video Companion. It also goes over some of the lengths this project went to in order to create a "reasonably secure" end product.

  • An unspoofable system tray icon and notification appears when webcam streaming or screen sharing is taking place to serve as a clear and persistent indication to the user of what is being shared
    • This tray icon and notification is created by the video sender so it's impossible for an attacker to forcefully obfuscate or remove it
    • This is especially important for screen sharing because whereas most webcams have an indicator light to inform the user of when they are in use; screen sharing has no such mechanism
  • One-way only communication from the video sending machine to the video receiving machine thus guaranteeing the security of the sender
    • This is crucial because the sender, typically sys-usb, has a lot of exposed hypervisor and hardware attack surface
      • This is due to having all USB devices in the form of the entire USB controller PCI device passed through to it
      • Additionally, for PCI passthrough sys-usb must be an HVM (as opposed to a PVH) domain which is far more complex and has proven to be the source of many more vulnerabilities in the Xen hypervisor
      • These vulnerabilities are very real and common, case in point:
        • XSA-373 of QSB #069-2021: "A malicious guest may be able to elevate its privileges to that of the host, cause host or guest Denial of Service (DoS), or cause information leaks."
        • XSA-325 of QSB #063-2020: HVM domains such as sys-usb may cause a use-after-free leading to a crash for which privilege escalation cannot be ruled out
        • XSA-337 of QSB #059-2020: "A malicious HVM with a PCI device (such as sys-net or sys-usb in the default Qubes OS configuration) can potentially compromise the whole system."
        • XSA-321 of QSB #058-2020: A vulnerability with the same level of impact as the previous one this time only affecting Intel processors
    • If a USB keyboard and mouse is in use (as opposed to PS/2 peripherals commonly used internally in laptops), sys-usb is responsible for routing the input of those devices to dom0
      • In this scenario, sys-usb compromise is essentially equivalent to dom0 compromise through keyboard/mouse input injection thus making it all the more important that we protect sys-usb
        • For example, an attacker could quickly inject the global default XFCE keyboard shortcut ALT+F2 to open xfce4-appfinder --collapsed followed by an arbitrary command to gain control of dom0
    • Other times, this is of ultimate concern because the most highly privileged virtual machine in the system, dom0, is in control of the USB devices
      • Although, passing through of individual USB devices with USBIP over Qubes RPC from dom0 was never a possibility in Qubes for security reasons
  • The attack surface of the video receiving machine is crafted to be as small as possible
    • GStreamer capsfilter (capabilities filter) is used to create a singular, small, homogeneous attack surface for accepting video
      • Video dimensions and frame rate capabilities are sanitized upon being pass to the video receiver to prevent the injection of additional capabilities
    • Only high quality and robust GStreamer "Base" and "Good" plugins are used to minimize the possibility of bugs
      • Additionally, only the most common and battle-hardened GStreamer components and formats are used
    • Any complex operations (such as video conversions where necessary) are done on the side of the sending machine where the video data is still inherently trusted
    • Only small parts of two kernel modules ever touch untrusted video data: v4l2loopback and the Video4Linux2 (V4L2) driver in mainline Linux
      • This is a massive improvement to what it would have been previously using USBIP over Qubes RPC for passing through a USB webcam device thereby exposing the entire Linux USB stack to a potential attacker
    • Kernel modules are reloaded between Qubes Video Companion sessions to ensure a clean state
  • The video dimensions and FPS parameters are sanitized by the video receiver to ensure they contain no extraneous GStreamer capabilities
  • No TCP/IP networking stacks are exposed
    • Communication is performed through file descriptors that run between virtual machines using the simple point-to-point protocol that is Qubes RPC (built upon Xen vchan under the hood)
  • Mitigates vulnerabilities in the webcam firmware
    • With Qubes Video Companion, the virtual machine receiving the webcam video stream never has direct hardware access to the webcam device thus rendering firmware tinkering impossible
    • Firmware vulnerabilities as demonstrated in this paper could allow an attacker to disable the webcam LED indicator or even perform a VM escape (or at least an escape to sys-usb)
    • Here is a good WIRED article on the state of firmware security and why it must not be trusted
  • Ability to separate the video and microphone capabilities that many webcams feature
    • Webcam microphones are often very sensitive picking up lots of background noise which serves as an information leak should the virtual machine it's being passed through to be compromised
      • This mitigates listening to keystrokes as a method of keylogging the entire system
        • Public implementations for conducting this type of attack in practice already exist so it's not an unrealistic concern
        • This also serves as a mitigation for other types of acoustic side-channel attacks (e.g. encryption key extraction through acoustic machine emanations)
      • Removes the possibility of hearing background conversations
    • Instead, connect only the desired microphone such as one that comes as part of a headset or even none at all using PulseAudio (please see the FAQ)
  • Conscious effort was made to base this project only on software with good security track records
    • GStreamer instead of FFmpeg
  • Allows for better isolation of complex (and unfortunately often proprietary) video conferencing software often used with webcams that is commonly the subject of many critical vulnerabilities (e.g. Zoom)
  • As has been well noted here, this project does not solve the privacy issue of an already compromised (as a result of a malicious USB device) sys-usb sniffing the webcam video stream and leaking that data to other USB devices
    • Leaking data over the network is already prevented through air-gapping sys-usb
    • However, the unidirectional communication of video data from sys-usb this project institutes 100% guarantees that it cannot be compromised in the first place through the use of a webcam
      • This assumes that the webcam itself isn't backdoored perhaps through a supply chain attack which have been on the rise lately (e.g. SolarWinds compromise)
  • All Git release tags are signed by the project maintainer's PGP key
    • All commits by the maintainer are also always signed with their PGP key
    • Should signing ever cease, assume compromise
    • Current maintainer 1: Elliot Killick PGP key
      • PGP key: 018F B9DE 6DFA 13FB 18FB 5552 F9B9 0D44 F83D D5F2
    • Current maintainer 2: Demi Marie Obenour (Key not attached to Keybase account)
      • PGP key: 8F3B D112 BD78 566D EABA 584F CFA7 7693 4CEF 6E3F
      • Signed proof

Frequently Asked Questions (FAQ)

What about audio?

In Qubes OS, audio is handled securely through the use of simple PulseAudio sinks.

The microphone of a webcam can be utilized by configuring it as the recording device for the desired qube in the Recording tab of the Volume Control application in dom0. Then, simply connect the microphone to the desired qube in the Qubes Devices system tray app at the bottom-right of the screen.

Audio is out of scope for this project in particular.

Why GStreamer instead of FFmpeg?

  • GStreamer has a much better security track record than FFmpeg
    • Even a broad search for all CVEs containing the term "GStreamer" shows far fewer vulnerabilities than what has specifically been assigned to the FFmpeg project
  • FFmpeg isn't included in the base Fedora repositories due to patent issues
    • Where FFmpeg is monolithic; GStreamer is modular allowing for the patent unencumbered components to be included in Fedora base repositories
  • GStreamer (at least the base and good plugins which is all we're using) has more efficient, clean and performant code
  • GStreamer has better cross-platform support for future development (Source)
  • GStreamer has superior documentation
  • FFmpeg has its advantages in some areas, but for this project, GStreamer is the way to go
    • FFmpeg is more flexible and easier to use (more "magic")
    • It has better and more special effects for video editing
    • Supports a wider range of formats and codecs

How does it work?

A basic overview is provided in the About section of this README.

For information on the GStreamer pipeline, check out pipeline.md and the accompanying diagrams in the visualizations folder. This will provide insight to the thought process that went into some of the design decisions made in this project along with illustrations of the pipeline internals.

The user interface components are created with GTK 3, GObject and AppIndicator (because GTK deprecated GtkStatusIcon).

Why can I perceive some latency in the video playback?

This issue will likely be fixed by switching entirely to MJPEG instead of the raw YUV video format for streaming video. See issues #16 and #13.

This means the CPU is at its limit (nearing or at 100% usage). To check this, install GNOME System Monitor (packaged as gnome-system-monitor) in the video receiving VM and assess the CPU usage for each of the processes and overall in the resources graph.

It's important to remember that for security reasons, qubes do not have access to the GPU and therefore, must rely entirely on the CPU even for graphical workloads.

To fix the latency, do one or more of the following:

  1. Remove or shrink the size of any windows playing back the video stream being shared to the video receiving VM
    • Just like in video editing, playing back raw, unencoded video in realtime is a very computationally expensive task that takes much more processing power than recording and in this case even sharing the video across VMs combined
    • For example, in OBS, right-click the video preview and uncheck Enable preview when recording
  2. Pause any videos from playing (e.g. YouTube videos) in any of the VMs
  3. Assign more vCPUs to the video receiving VM
    • The video rendering workload lends decently to multithreading so the more vCPUs the better
    • The vCPU count can be changed in the settings for that qube
  4. Reduce the resolution and/or frame rate the webcam is recording at to a supported lower quality setting

Contributing

You can start by giving this project a star! High quality PRs are also welcome! Take a look at the issue tracker if you're looking for things that need improvement. Other improvements such as more elegant ways of completing a task, code cleanup and other fixes are also welcome.

Alternatively, for ideas on what you can contribute to the wider Qubes OS project, take a look at the "help wanted" Qubes issues and available GSoC projects.

The video camera icon used in the project logo is by Рытикова Людмила licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license. As a result, the logo as a whole is under the same license. The portion of the logo surrounding the video camera icon is by Max Andersen, used with written permission.

This project is the product of an independent effort that is not officially endorsed by Qubes OS.

Tested Working Applications

  • Cheese
  • Chromium-based browsers (e.g. Brave and Google Chrome)
  • Firefox
    • This patch for v4l2loopback is necessary to get this working
  • Open Broadcaster Software (OBS)
    • For the Video Capture Device (V4L2) source click on the Properties settings cog and use video format Planar YUV 4:2:0 (as opposed to YV12 (Emulated)) and uncheck Use buffering for optimal performance
  • Zoom

Webcam Hardware Compatibility List (HCL)

This is the list of webcams confirmed to work with Qubes Video Companion.

The model of a given webcam can be found by running v4l2-ctl --list-devices in the virtual machine with the webcam device attached.

  • Logitech C922 Pro Stream Webcam
  • SunplusIT Inc Integrated Camera

Mailing List Thread

End Goals

  • Implement a solution for secure webcam utilization that sufficiently addresses the concerns brought up in this in-depth paper on webcam firmware security: iSeeYou: Disabling the MacBook Webcam Indicator LED (Google Scholar) by Johns Hopkins University
    • The end product should be capable of fully protecting at risk individuals such as those documented in the case studies of this MIT paper in practice (assuming they are Qubes users)
  • Effectively solve two long-standing Qubes issues making using a webcam in Qubes OS a dodgy, insecure and computationally expensive (in CPU and RAM) experience:
    • Cannot use a USB camera: #4035
    • Feature: Trusted stream for webcam input: #2079
  • Add secure screen sharing functionality between qubes
    • Feature: Screen sharing between AppVMs: #6426

qubes-video-companion's People

Contributors

demimarie avatar elliotkillick avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qubes-video-companion's Issues

Building deb pkg fails

I'm probably doing something wrong:

$ dpkg-source --before-build .
$ dpkg-buildpackage -us -uc   
dpkg-buildpackage: info: source package qubes-video-companion
dpkg-buildpackage: info: source version 1.0.0-1
dpkg-buildpackage: info: source distribution unstable
dpkg-buildpackage: info: source changed by Elliot Killick <[email protected]>
dpkg-buildpackage: info: host architecture amd64
 dpkg-source --before-build .
 fakeroot debian/rules clean
dh clean
   dh_auto_clean
        make -j8 clean
make[1]: Entering directory '/home/user/src/qubes/qubes-video-companion'
make -C doc clean
make[2]: Entering directory '/home/user/src/qubes/qubes-video-companion/doc'
rm -f qubes-video-companion.1.gz
make[2]: Leaving directory '/home/user/src/qubes/qubes-video-companion/doc'
make[1]: Leaving directory '/home/user/src/qubes/qubes-video-companion'
   dh_clean
 dpkg-source -b .
dpkg-source: error: can't build with source format '3.0 (quilt)': no upstream tarball found at ../qubes-video-companion_1.0.0.orig.tar.{bz2,gz,lzma,xz}
dpkg-buildpackage: error: dpkg-source -b . subprocess returned exit status 255

Where is the source for qubes-video-companion, if any?

installing process

Hello.
Thank you to contributor this feature look fantastic.

I'm just a newbie with qubes OS. i would like the screen sharing functionality.

I try this to install :
sudo qubes-dom0-update qubes-video-companion

but it indicates a no match.

i think there is somthing i did not understand in installation process. is someone can light me?

Improve Performance Through Better Multithreading

I noticed adding more vCPUs to a video receiving VM scales decently but after running the numbers (tallying up CPU usage differences between 2 and 4 vCPUs) I think there is indeed some amount of multithreading going on and suspect there's still room for improvement.

I found an interesting article that said it was able to accomplish 3.2x speed up to raw video conversion with a ParallelizedTaskRunner they patched into the videoconvert element of GStreamer. [1] We use videoconvert on the screen sharing video sender because the default X11 format (BGRx) is incompatible with anything the v4l2sink for v4l2loopack accepts. Also, to make sure there is only one homogeneous attack surface across both webcam streaming and screen sharing. So, first of all we could speed up that using this patch.

I wonder if we could implement the same work for the rawvideoparse GStreamer element on the side of the video receiving VM to achieve dramatic performance improvements.

I also found some GStreamer documentation for GstTask in general which maybe we could use to (possibly, I'm not sure) implement this even without patching GStreamer if we wanted to. [2]

Of course, to take advantage of any of this we would have to rewrite the GStreamer components in a real programming language such as Python or C (GStreamer has binding for both of these languages through GI/GObjects) as opposed to shell. Note that we wouldn't necessarily have to do away with all the shell but essentially we would at least have to replace any instance of gst-launch-1.0 with a Python/C program utilizing the GStreamer library.

[1] https://coaxion.net/blog/2017/10/multi-threaded-raw-video-conversion-and-scaling-in-gstreamer/
[2] https://gstreamer.freedesktop.org/documentation/gstreamer/gsttask.html

use webcam attached to dom0

Hello,

I want to use my internal webcam of my notebook in the Zoom app.
Currently it is attached to dom0, as it is connected as an usb device.

I have installed it on dom0 and in the appVM via make install
I faced the same issue as described in issue #19 and I fixed it by coping the script from version 1.
The ui opens when I run qubes-video-companion webcam in the appVM.
I can select dom0 as source but the webcam is not connected.

Is there any step I was missing to make it run?
Can you please help me solve it?

ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.

TBH I have no idea if I'm doing it correctly. My procedure:

  1. Compile deb package
  2. Install in work VM (here I want to use C922) and in sys-usb VM (camera is connected to this VM) package qubes-video-companion_1.0.0-1_all.deb
  3. Change qubes-video-companion so it points to sys-usb instead of dom0
  4. First call DEBUG=1 qubes-video-companion webcam asked me for permission and I answered YES, then I had to point to sys-usb

Results looks as follows:

work% DEBUG=1 qubes-video-companion webcam
+ set -E
+ trap exit ERR
+ video_source=webcam
+ case "$video_source" in
+ qvc_service=qvc.Webcam
+ qvc_lock_file=/run/lock/qubes-video-companion
+ '[' -f /run/lock/qubes-video-companion ']'
+ trap exit_clean EXIT
+ sudo touch /run/lock/qubes-video-companion
+ /usr/share/qubes-video-companion/video/setup.sh
+ set -E
+ trap exit ERR
+ source /usr/share/qubes-video-companion/video/common.sh
++ '[' 1 == 1 ']'
++ set -x
++ set -E
++ trap exit ERR
+ test_v4l2loopback
+ PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
+ modinfo v4l2loopback
+ sudo modprobe v4l2loopback 'card_label=Qubes Video Companion' exclusive_caps=1
+ sudo setfacl -m user:user:rw /dev/video0
+ qrexec-client-vm sys-usb qvc.Webcam /usr/share/qubes-video-companion/video/receiver.sh --buffer-size=0 --filter-escape-chars-stderr
+ set -E
+ trap exit ERR
+ read -r untrusted_width untrusted_height untrusted_fps
Starting webcam stream at 640x480 30 FPS...
++ sanitize_cap 640
++ local cap_value=640
++ echo 640
++ tr -cd 0-9
+ width=640
++ sanitize_cap 480
++ local cap_value=480
++ echo 480
++ tr -cd 0-9
+ height=480
++ sanitize_cap 30
++ local cap_value=30
++ echo 30
++ tr -cd 0-9
+ fps=30
+ '[' 640 ']'
+ echo 'Receiving video stream at 640x480 30 FPS...'
Receiving video stream at 640x480 30 FPS...
+ frame_rate=30/1
+ gst-launch-1.0 fdsrc '!' queue '!' capsfilter caps=video/x-raw,width=640,height=480,framerate=30/1,format=I420,colorimetry=2:4:7:1,chroma-site=none,interlace-mode=progressive,pixel-aspect-ratio=1/1,max-framerate=30/1,views=1 '!' rawvideoparse use-sink-caps=true '!' v4l2sink device=/dev/video0 sync=false
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
Additional debug info:
gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming stopped, reason not-negotiated (-4)
++ exit
++ exit
+ exit_clean
+ exit_code=141
+ /usr/share/qubes-video-companion/video/destroy.sh
+ set -E
+ trap exit ERR
+ source /usr/share/qubes-video-companion/video/common.sh
++ '[' 1 == 1 ']'
++ set -x
++ set -E
++ trap exit ERR
+ test_v4l2loopback
+ PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
+ modinfo v4l2loopback
+ sudo modprobe -r v4l2loopback videodev
+ sudo rm -f /run/lock/qubes-video-companion
+ '[' webcam == webcam ']'
+ '[' 141 == 141 ']'
+ echo 'The webcam device is in use! Please stop any instance of Qubes Video Companion running on another qube.'
The webcam device is in use! Please stop any instance of Qubes Video Companion running on another qube.
+ exit 1

Testing procedure have to be described better since I have no idea if I'm doing it correctly.

Personally I would be glad to see this on Qubes OS minisummit: https://twitter.com/3mdeb_com/status/1412759830062899210

Allow users to manually select webcam parameters

For resolution and frame rate, we can make a reasonable default choice based on heuristics, such as “highest resolution, then fastest frame rate” or “fastest frame rate, then highest resolution”. However, users might very well want to override the defaults. Ideally, this could be done via a GUI, but a configuration file would be okay for now.

No names found running the script

Hello! Thanks for your work

Sorry it's probably a newbie question, I don't have any experience at all in building from source, but I really need this tools for my everyday work.

I have initialized git in the folder, but when I try to run the script (both debian and fedora) it gave me the follwing error:

[user@disp9487 qubes-video-companion-master]$ DEBUG=1 ./build/create-rpm.sh
+ set -E
+ set -euo pipefail
+ trap exit ERR
+ package_type=vm
+ case $package_type in
+ :
+ case $0 in
+ local_dir=././build
+ cd ././build
+ pwd
/home/user/QubesIncoming/work/qubes-video-companion-master/build
+ author_fpr=018FB9DE6DFA13FB18FB5552F9B90D44F83DD5F2
+ gpg --import author.asc
gpg: key F9B90D44F83DD5F2: "Elliot Killick <[email protected]>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1
+ cd ..
++ git describe --abbrev=0
fatal: No names found, cannot describe anything.
+++ exit
+ version_tag=
++ exit

Which is the name that it need to find?
Any helps will be appreciated
Thanks in advance

'scripts/set-webcam-format.sh': No such file or directory

Clone repo and try:

$ tar czvf qubes-video-companion_1.0.0.orig.tar.gz qubes-video-companion
$ cd qubes-video-companion
$ dpkg-source --before-build .
$ dpkg-buildpackage -us -uc

Result:

(...)
make[1]: Entering directory '/home/debian/qubes/qubes-video-companion'
make install-vm DESTDIR=/home/debian/qubes/qubes-video-companion/debian/qubes-video-companion
make[2]: Entering directory '/home/debian/qubes/qubes-video-companion'
install -d /home/debian/qubes/qubes-video-companion/debian/qubes-video-companion/etc/qubes-rpc
install -D qubes-rpc/services/qvc.Webcam qubes-rpc/services/qvc.ScreenShare /home/debian/qubes/qubes-video-companion/debian/qubes-video-companion/etc/qubes-rpc
install -d /home/debian/qubes/qubes-video-companion/debian/qubes-video-companion/usr/share/qubes-video-companion/ui
install -D ui/*.py ui/*.sh /home/debian/qubes/qubes-video-companion/debian/qubes-video-companion/usr/share/qubes-video-companion/ui
install -d /home/debian/qubes/qubes-video-companion/debian/qubes-video-companion/usr/share/qubes-video-companion/scripts
install -D scripts/set-webcam-format.sh /home/debian/qubes/qubes-video-companion/debian/qubes-video-companion/usr/share/qubes-video-companion/scripts
install: cannot stat 'scripts/set-webcam-format.sh': No such file or directory
make[2]: *** [Makefile:45: install-both] Error 1
make[2]: Leaving directory '/home/debian/qubes/qubes-video-companion'
make[1]: *** [debian/rules:7: override_dh_auto_install] Error 2
make[1]: Leaving directory '/home/debian/qubes/qubes-video-companion'
make: *** [debian/rules:4: binary] Error 2
dpkg-buildpackage: error: fakeroot debian/rules binary subprocess returned exit status 2

Of course removing reference to that script in Makefile leads to successful package build.

Document requirements or improve error message

In order to run build/create-rpm.sh you need rpmdevtools.

./buid/create-rpm.sh: line 76: rpmdev-setuptree: command not found

So either:

  • detect that in the script and print a better help message, or
  • install it automatically, or
  • document it in the README

GPG key expired

work% qubes-video-companion webcam
The v4l2loopback kernel module is not installed. Please run the following script to install it: /usr/share/qubes-video-companion/scripts/v4l2loopback/install.sh
work% /usr/share/qubes-video-companion/scripts/v4l2loopback/install.sh
gpg: key B65019C47F7A36F8: "IOhannes m zmölnig <[email protected]>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1
Cloning into 'v4l2loopback'...
remote: Enumerating objects: 3226, done.
remote: Counting objects: 100% (201/201), done.
remote: Compressing objects: 100% (133/133), done.
remote: Total 3226 (delta 104), reused 142 (delta 68), pack-reused 3025
Receiving objects: 100% (3226/3226), 1.11 MiB | 2.08 MiB/s, done.
Resolving deltas: 100% (1920/1920), done.
gpg: Signature made Sun 19 Apr 2020 07:10:13 PM CEST
gpg:                using RSA key 7405E745574809734800156DB65019C47F7A36F8
gpg: Good signature from "IOhannes m zmölnig <[email protected]>" [expired]
gpg:                 aka "IOhannes m zmölnig (forum::für::umläute - Network Operation Center) <[email protected]>" [expired]
gpg:                 aka "IOhannes m zmölnig (Debian/GNU) <[email protected]>" [expired]
gpg:                 aka "IOhannes m zmölnig (forum::für::umläute) <[email protected]>" [expired]
gpg:                 aka "Johannes Zmölnig (University of Music and Performing Arts - Graz) <[email protected]>" [expired]
gpg:                 aka "IOhannes m zmölnig (IEM - Network Operation Center) <[email protected]>" [expired]
gpg:                 aka "IOhannes m zmölnig (mur.at - Verein zur Förderung von Netzwerkkunst) <[email protected]>" [expired]
gpg:                 aka "IOhannes m zmölnig <[email protected]>" [expired]
gpg:                 aka "[jpeg image of size 5377]" [expired]
gpg: Note: This key has expired!
Primary key fingerprint: 7405 E745 5748 0973 4800  156D B650 19C4 7F7A 36F8
Failed to verify v4l2loopback author PGP key!
work% qubes-video-companion webcam 

Send the video parameters as packed binary

This has less attack surface than the read command of bash, and makes for easier validation.

This will require that the receiver program be ported from shell to another language, such as Python.

Split sender and receiver into separate packages

The sender and receiver have different dependencies and should be separately installable. For instance, the sender doesn’t require any out of tree kernel modules, while the receiver does.

Default Webcam Resolution May Be Undesirable

This is in reference to the "Why is the webcam resolution or frame rate lower than what my webcam is capable of?" FAQ in the README. Please look there for the temporary, manual fix for this issue.

The issue occurs whenever I plug in and out my webcam, restart my computer, etc. Also noteworthy, the good settings I set manually don't get unset if I rmmod the V4L2 videodev driver and reload it. Could this mean it's possibly not something to do with the V4L2 driver (at least directly)?

Note, that I'm streaming my webcam from dom0 in Qubes R4.0 stable which uses an older version of the Linux kernel than Qubes R4.1 which is currently under development. Perhaps somebody could see if this issue is reproducible with the newer Linux kernel?

Either that, or somebody with their webcam assigned to sys-usb (which has a more up-to-date Linux kernel) could see if this issue still occurs. I don't have access to a sys-usb because I require a USB sound card which needs to be assigned to dom0 where the other Qubes audio components are to work. I've been thinking about getting a PCI sound card but because I run Qubes on my desktop at home, a physical USB attack isn't really in my threat model anyway.

My webcam default (bad, low resolution, laggy) settings (v4l2-ctl --device /dev/video0 --all) are:

Width/Height      : 640/480
Pixel Format      : 'YUYV'
Frames per second: 30.000 (30/1)

As an added tidbit, running this simple GStreamer pipeline (gst-launch-1.0 -v v4l2src ! xvimagesink) for viewing the webcam video (without any capabilities manually specified on the pipeline) set my V4L2 device settings to something even weirder:

Width/Height      : 2304/1536
Pxel Format      : 'YUYV'
Frames per second: 2.000 (2/1)

v4l2sink missing?

image

Thank you for your work, looks very neat. :) Wanted to help test it.

First had to install qv4l2, v4l-utils, gstreamer1-plugins-base-devel, (gstreamer1-plugins-good). (Please add this to documentation?)
Installed those in AppVM and sys-usb, now I get this. Not sure what it's about, because afaict v4l2sink is provided by plugins-good?

Use v4l2 ioctls directly

v4l2-ctl’s output format appears to be meant for human use, rather than programmatic use. A better approach would be to use the v4l2 ioctls directly.

build/create-rpm.sh fails on gpg import

[user@untrusted qubes-video-companion]$ DEBUG=1 ./build/create-rpm.sh 
+ set -E
+ trap exit ERR
+ '[' '' == dom0 ']'
+++ readlink -f ./build/create-rpm.sh
++ dirname /tmp/qubes-video-companion/build/create-rpm.sh
+ local_dir=/tmp/qubes-video-companion/build
+ cd /tmp/qubes-video-companion/build
+ gpg --import author.asc
gpg: key F83DD5F2: no valid user IDs
gpg: this may be caused by a missing self-signature
gpg: Total number processed: 1
gpg:           w/o user IDs: 1
++ exit

Even if I comment out things related to gpg signature I eventually getting this error:

make[1]: Entering directory '/home/user/rpmbuild/BUILD/qubes-video-companion-1.0.0/doc'
pandoc -s -f rst -t man -o qubes-video-companion.1 qubes-video-companion.rst
gzip -f qubes-video-companion.1
install -d /home/user/rpmbuild/BUILDROOT/qubes-video-companion-1.0.0-1.fc26.x86_64/usr/share/man/man1
install -Dm 644 qubes-video-companion.1.gz /home/user/rpmbuild/BUILDROOT/qubes-video-companion-1.0.0-1.fc26.x86_64/usr/share/man/man1
make[1]: Leaving directory '/home/user/rpmbuild/BUILD/qubes-video-companion-1.0.0/doc'
install -d /home/user/rpmbuild/BUILDROOT/qubes-video-companion-1.0.0-1.fc26.x86_64/usr/share/licenses/qubes-video-companion
install -Dm 644 LICENSE /home/user/rpmbuild/BUILDROOT/qubes-video-companion-1.0.0-1.fc26.x86_64/usr/share/licenses/qubes-video-companion
+ /usr/lib/rpm/find-debuginfo.sh --strict-build-id -m --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 110000000 /home/user/rpmbuild/BUILD/qubes-video-companion-1.0.0
+ '[' noarch = noarch ']'
+ case "${QA_CHECK_RPATHS:-}" in
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
Compiling /home/user/rpmbuild/BUILDROOT/qubes-video-companion-1.0.0-1.fc26.x86_64/usr/share/qubes-video-companion/ui/user_interface.py ...
  File "/usr/share/qubes-video-companion/ui/user_interface.py", line 33
    print('Video source does not exist:', self.video_source, file=sys.stderr)
                                                                 ^
SyntaxError: invalid syntax

error: Bad exit status from /var/tmp/rpm-tmp.uXVhIu (%install)


RPM build errors:
    Bad exit status from /var/tmp/rpm-tmp.uXVhIu (%install)
++ exit

PGP verification issue

Hi @ElliotKillick,
to do git verify-tag v1.0.4 I need your public key, where I can get and where I can confirm your fingerprint?

Your Github says:

Open/libre technology advocate, avid developer, infosec aficionado, student & cybersecurity TA @ UofT SCS. PGP: 018F B9DE 6DFA 13FB 18FB 5552 F9B9 0D44 F83D D5

but

debian@debian:~/qubes/qubes-video-companion$ git verify-tag v1.0.4
gpg: Signature made Wed 21 Apr 2021 07:34:10 AM CEST
gpg:                using EDDSA key 018FB9DE6DFA13FB18FB5552F9B90D44F83DD5F2
gpg: Can't check signature: No public key

It looks like you missing F2 at the end.

Run gstreamer in a sandbox

We can use bubblewrap to run the various gstreamer components in a tight sandbox based on seccomp and namespaces. This helps ensure that if an attacker does manage to exploit a vulnerability in gstreamer, it will be difficult to cause further damage.

Integrate Webcam Function with "Qubes Devices" System Tray Menu

Having the webcam functionality integrated into the Qubes Devices system tray menu would lead to a much better user experience for using a webcam in Qubes OS.

Note that this would still leave the screen sharing functionality of Qubes Video Companion with no GUI to use with. A special GUI application would probably have to be made for the screen sharing functionality as that has nothing to do with devices and has a much different architecture. Where sharing a webcam is a one-to-many sharing operation; sharing screens would be a many-to-many relationship because each VM has its own screen which they can share while also receiving the screen of another VM.

Firefox Can Only Play a Still Frame of Video

Firefox only seems to be able to play a single frame of video. I've already diagnosed why this is happening with both GStreamer and FFmpeg test commands leading to the same root issue.

Firefox doesn't seem to like the YUV video format but when I tried an MJPEG stream (stream of JPEG images, which is a common format for webcams) it works fine and plays the video back seamlessly.

We could add a conversion to the MJPEG format but I tested that and it results in big latency increase (not to mention the added attack surface). Additionally, to do that GStreamer actually relies on a libav (fork of FFmpeg) conversion algorithm that got bindings added to it for GStreamer. This is the element in question: https://gstreamer.freedesktop.org/documentation/libav/avenc_mjpeg.html. This means it's not packaged in Fedora due to the patent issues with FFmpeg.

So, with the problem diagnosed I'm going to try and make quick work on finding where the bug is so it can be patched. Firefox is the only application I've tested that has had problems so it may be a Firefox bug with YUV formats. I looked it up and Firefox should have full support for YUV webcam video just like Chromium but that doesn't appear to be the case.

Going to try and fix this ASAP because I hate to leave Firefox at a disadvantage.

Move to the @QubesOS organization

Qubes Video Companion will be a core part of a future Qubes OS release. This requires that it be moved to the @QubesOS organization on GitHub. Would creating a blank repository in @QubesOS and you creating a PR work?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.