Skip to content

Architecture

Tres Finocchiaro edited this page Jan 28, 2021 · 13 revisions

Objective

The objective of this document is to explain the architectural design of QZ Tray and its components.

Overview

From a technical perspective, QZ Tray is a Java application which uses a WebSocket connection to send and receive data with a JavaScript client (usually a Web Browser).

JavaScript

JavaScript is required to communicate with QZ Tray though the API and uses the living standard as established by https://www.ecma-international.org/.

WebSocket

QZ Tray is able to communicate with the web browser by utilizing a secure WebSocket (wss://) running on localhost using a self-signed certificate. With QZ Tray installed and running, this certificate can be examined by clicking Advanced, Diagnostic, Browse Shared folder... (e.g C:\Program Data\qz\ssl).

  • WebSocket encryption utilizes a 825 day SSL-Cert created from a 20 year CA-Cert both created from 2,048 private keys (subject to change)
  • WebSocket client is governed by JavaScript's WebSocket living standard. To examine this certificate in the browser, please visit https://localhost:8181 on a machine with QZ Tray installed.
  • WebSocket server is managed by Eclipse foundations' jetty://. For library version information, please visit http://localhost:8182 on a machine with QZ Tray installed.
  • Messages are constructed in JSON format with a message, timestamp, uid and trailing digital signature required for all [privileged actions](#privileged-actions].
    {
       "certificate": "-----BEGIN CERTIFICATE-----...",
       "promise": {},
       "timestamp": 1611603956527,
       "uid": "bcntkb"
    },
    {
       "call": "printers.find",
       "promise": {},
       "params": {},
       "timestamp": 1611603983918,
       "uid": "77hiy0",
       "signature": "JbfqcFNQ6iF..."
    }

Java

Java is required to run QZ Tray. Java LTS is preferred, but not required. For minimum requirements please see https://qz.io/wiki/faq#java-versions. Some components of QZ Tray also require Java FX, which is provided as a module by the Desktop installer. It is possible to run QZ Tray without Java FX if the format: 'html' APIs are avoided.

In addition, several 3rd party libraries are used for various components. An comprehensive list of these libraries and their versions are available by visiting http://localhost:8182 on a machine with QZ Tray installed.

An example of components: (non-comprehensive)

Component Use
JNA Access native C/C++/Objective-C libraries
JSSC Access serial/com ports
HID4Java Access HID devices
PureJavaHidAPI Access HID devices
Jetty All HTTP traffic (WebSocket)
PDFBox PDF render, rasterization and printing
JavaFX HTML render, rasterization and printing

Privileged Actions

QZ Tray considers access to local resources as privileged and requires the following to be digitally signed using the following algorithms:

  • Signature Strength

  • CA Providers

    • Digital signatures must originate from a the QZ Industries, LLC Root-CA and are issued as part of the support and licensing package.
    • Alternately, the Root-CA can be overridden for increased control and security.

Printers

QZ Tray utilizes the Java awt libraries for accessing locally installed printers as well as a combination of platform-specific registries available for obtaining information not exposed to Java using a mixture of command line and native access techniques to access the Windows Printer Spool and CUPS, respectively.

Printing is a "one-way" transmission as QZ Tray is capable of sending data to a printer, but information is not sent back which is not otherwise available to the spooler subsystem. Two-way communication is achievable via USB or Serial.

USB Devices

QZ Tray utilizes two techniques for accessing USB devices, USB (raw) and HID. Both provide standard two-way communication for attached USB devices including but not limited to device iteration, sending and receiving raw data and listening for events, such as adding and removing devices.

Serial Devices

QZ Tray offers the ability to iterate over, open and communicate with locally attached serial devices including port settings such as baud rate, stop bits, parity, flow control.

File IO

QZ Tray offers the ability to read and write files to a known list of approved locations. These locations can be either Shared or Sandboxed, depending on the developer's intentions. In all case, the locations are limited ONLY to that of which QZ Tray has created, or have been explicitly allowed through intentional, manual modification of the QZ Tray installation.

TCP Sockets

As of QZ Tray 2.1.4, the ability to read and write to TCP sockets based on IP information.

Permissions

File Permissions

QZ Tray is installed using Administrator or root privileges, but is launched using standard, user permissions. QZ Tray will read and write only to resources a user has permission to write to. All file operations are done within the confines of a User profile or directory with exception of the shared directory. Upon installation, QZ Tray will create and grant shared access to a shared directory. This shared directory can be examined by clicking Advanced, Diagnostic, Browse Shared folder... (e.g C:\Program Data\qz).

Firewall

QZ Tray predominantly runs on port 8181, on a secure WebSocket and on port 8182 on an insecure WebSocket.

Due to the availability of ports, QZ Tray will attempt to open on ONE of the following ports.

Port Primary Secondary Tertiary Quaternary
🔒 Secure 8181 8282 8383 8484
🔓 Insecure 8182 8283 8384 8485
Windows Firewall

To ensure viable communication, QZ Tray whitelists these ports in the Windows Firewall for all traffic using an inbound Firewall rule.

AutoStart

QZ Tray will automatically start with the computer, however it also registers a URI handler (qz:launch) so that it can be launched by href.