4

How to properly Suppress the

localhost wants to access connected printers Untrusted Website

modal when accessing printers?

I've tried to create a certificate through this OpenSSL command:

openssl req -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -keyout server.key -out server.crt

Then addeed the override like this:

authcert.override=server.crt

in the qz-tray.properties file.

However it is still the same the dialog box is not suppressed. What could be wrong?

This is the complete cert properties file:

authcert.override=C:\\Program Files\\QZ Tray\\auth\\server.crt
wss.alias=qz-tray
wss.keypass=keypass
wss.storepass=storepass
wss.host=0.0.0.0
quarks
  • 33,478
  • 73
  • 290
  • 513
  • @qz-support can you help check this one? Thanks! – quarks Oct 21 '16 at 03:48
  • There's a signing step, outlined in several different server languages available from the wiki/resources folder. Which server-side language are you using? – tresf Oct 21 '16 at 04:20
  • @QZSupport We will be deploying the web app with Electron(http://electron.atom.io/) which will be totally localhost – quarks Oct 21 '16 at 05:01
  • I mean the web app will be for a physical Kiosk – quarks Oct 21 '16 at 05:27
  • We also have tried this: https://developer.salesforce.com/blogs/developer-relations/2011/05/generating-valid-self-signed-certificates.html Still getting the Allow popup – quarks Oct 21 '16 at 05:55
  • For offline or pure client-side signing, this will do it:. https://github.com/qzind/tray/blob/2.0/assets/signing/sign-message.js – tresf Oct 21 '16 at 17:45
  • The salesforce article will work fundamentally for generating any old certificate and private key, but you should use 2048 for complexity. – tresf Oct 24 '16 at 20:52
  • @QZSupport if we purchase the license or support from your website will it help? We just want to take this "Allow" thing away without any hassle. – quarks Oct 27 '16 at 01:15
  • yes, the support package comes with a 1 year certificate -- that doesn't require any custom `properties` or command line shims -- as well as remote help for configuring it in your environment. – tresf Oct 27 '16 at 03:07

2 Answers2

8

The qz-tray.properties override will be introduced with version 2.0.2 and at the time of writing this, 2.0.1 is the latest stable release.

Possible options:

  • Wait for 2.0.2 / compile from source and use the qz-tray.properties override value

    • -- OR --
  • Wait for 2.0.2 / compile from source but provide the certificate at packaging time, which will allow the override.crt to be distributed directly with the installer.

    ant nsis -Dauthcert.use=override.crt
    
    • -- OR --
  • Use 2.0.1 and start the software with the certificate override via command line. e.g:

    java -DtrustedRootCert=override.crt -jar qz-tray.jar
    

Since the latter option requires modification of the QZ Tray desktop launcher, this will ultimately lead to non-obvious issues when auto-start is enabled (e.g. auto-start on Windows is triggered by qz-tray.exe which will launch without the -DtrustedRootCert parameter).

This is why the 2.0.2 feature of providing the certificate permanently in qz-tray.properties is much preferred. Note, compiling the latest QZ Tray is a few quick steps.

But this is only half of the battle. To suppress the security warnings, each message must be digitally signed. This is where the server.key comes into play. We call this private-key.pem in our examples.

Signing is generally done server-side although can be done client-side with risk of key leakage. This process is explained best in the sign-messages wiki.

Signing Messages

PHP Signing Example:

<? // sign-message.php

$KEY = 'private-key.pem'; // or 'server.key', etc
$req = $_GET['request'];  // i.e. 'toSign' from JS
$privateKey = openssl_get_privatekey(file_get_contents($KEY));
$signature = null;
openssl_sign($req, $signature, $privateKey);
if ($signature) {
    header("Content-type: text/plain");
    echo base64_encode($signature);
    exit(0);
}
echo '<h1>Error signing message</h1>';
exit(1);

?>

JavaScript:

qz.security.setSignaturePromise(function(toSign) {
    return function(resolve, reject) {
       $.ajax("/foo/bar/sign-message.php?request=" + toSign).then(resolve, reject);
    };
});

qz.security.setCertificatePromise(function(resolve, reject) {
    $.ajax("/foo/bar/digital-certificate.txt").then(resolve, reject); // or `server.crt`, etc
});

Note: To prevent key leakage, the private key should always be kept in a directory inaccessible by a web browser.

tresf
  • 7,103
  • 6
  • 40
  • 101
  • What is the purpose of signing in qz tray, can it be disabled?. Is it not sufficient to have CORS settings on qz tray side? – pinkpanther Mar 31 '21 at 20:16
  • `What is the purpose of signing in qz tray` This may be better for its own question, but it's to verify the website is who it says it is, which is tricky to do securely in JavaScript. `can it be disabled` yes, but you have to recompile (which is trivial). `Is it not sufficient to have CORS settings on qz tray side?` From a security perspective, that would probably suffice, but then each install would require special configuration. – tresf Apr 01 '21 at 18:25
7

Just suppress warning

If you're using QZ Tray in an isolated machine (like in my case), local environment or for any reason you don't need to encrypt messages and just wanna get rid of the warning message you can disable the warning dialog itself.

Disclaimer: This method is not supposed to be used in production, messages won't be signed, any website can talk to your hardware, use under your own risk.

  1. Clone the QZ Tray repository ( https://github.com/qzind/tray.git ).
  2. Fulfill the compiling dependencies: Ant, Java, NSIS (Windows). If you're using windows I recommend you use Chocolatey, with Chocolatey it's straightforward to install those dependencies.
  3. Get a code editor or IDE (I used IntelliJ Idea community edition).
  4. Navigate and edit /src/qz/ws/PrintSocketClient.java change line 476

    From this:

    if (cert.isTrusted() && cert.isSaved()) {
    

    into

    if (cert.isSaved()) {
    
  5. Navigate and edit /src/qz/ui/GatewayDialog.java change line 92

    From

    allowButton.setEnabled(!persistentCheckBox.isSelected() || cert.isTrusted());
    

    into

    allowButton.setEnabled(true);
    
  6. Compile using:

    • ant nsis for windows
    • ant pkgbuild for MacOS
    • ant makeself for linux

    Actually this won't only compile but also creates the installer. QZ team did a great job automatizing everything.

  7. Install QZ tray using the installer just created.

  8. The first time you'll see the warning but now you can Remember the decision to Allow forever.

I suggest to use self-signed certificates or pay premium support if you need a truly secure setup.

ZooMMX
  • 838
  • 9
  • 14
  • 2
    Bypassing the dialogs gives all webpages access to USB ports, serial ports, printers, and in some cases the local filesystem. Self-signed instances are the most secure (more-so than the paid certificates) because only those with access to the private key will ever show as "Trusted" . Advising code modifications over the accepted answer is a very dangerous proposition, as any unsuspecting site can just talk to one's hardware. It should be against most basic ethical standards to propose this without a very, very strong warning. – tresf Sep 05 '19 at 19:13
  • "messages won't be encrypted" is misleading. "messages won't be signed" is correct, but a consumer won't know what that means. "Any website can talk to your hardware" is most accurate. Regarding encryption: HTTPS will encrypt the transport for HTTPS pages. QZ Tray doesn't do any further encryption, it's all on the transport layer. Instead, SHA1 digital signatures are used for validation. Removing this validation means any website can talk to your hardware without your knowledge, which should be terrifying to any IT professional. – tresf Sep 05 '19 at 19:17
  • @tresf you're right, I edited this answer with your warnings and corrections. – ZooMMX Sep 12 '19 at 00:42
  • Thanks, however the recommendations for premium support are not needed. Self-signed certificates are arguably most secure so it would be most accurate (as well as less soliciting) to leave out any specificities involving payment. – tresf Sep 12 '19 at 15:27
  • @tresf thanks to you. I modified that suggestion. I still think that paying support is actually advisable in my experience but also to use a self-signed certificate is so I suggest both. – ZooMMX Sep 14 '19 at 16:18