-
Notifications
You must be signed in to change notification settings - Fork 277
Architecture
The objective of this document is to explain the architectural design of QZ Tray and its components.
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).
- 🌐 Web Browser
JavaScript is required to communicate with QZ Tray though the API and uses the living standard as established by https://www.ecma-international.org/.
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 a20
year CA-Cert both created from2,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 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 |
QZ Tray considers access to local resources as privileged and requires the following to be digitally signed using the following algorithms:
-
Signature Strength
- SHA1 (deprecated)
- SHA256
- SHA512 (default)
Signing should be done as a server-side task to avoid private key exposure. Signing examples for most popular programming languages are provided for convenience purposes:master/assets/signing
. Video tutorials are available as well youtube.com/qzind.
-
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.
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.
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.
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.
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.
As of QZ Tray 2.1.4, the ability to read and write to TCP sockets based on IP information.
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
).
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 |
To ensure viable communication, QZ Tray whitelists these ports in the Windows Firewall for all traffic using an inbound Firewall rule.
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
.