From 495bf51ac8118947b2416333f7f3ed50495d17da Mon Sep 17 00:00:00 2001
From: Patrick Wagstrom <160672+pridkett@users.noreply.github.com>
Date: Sat, 21 Sep 2024 18:01:42 -0400
Subject: [PATCH 1/2] fix: allow TLS with remote docker when using public CA

This provides a small fix that allows you to define docker hosts that
you can connect with in three different ways:

1. Mutual TLS, docker host uses non-standard CA
2. Mutual TLS, docker host uses standard CA
3. No Authentication, docker host uses non-standard CA
4. No authentication, docker host uses standard CA

In the previous implementation only condition 1 and 4 were allowed. This
makes condition 2 and 3 possible. The logic is a little messy, but it
works.

DCO-1.1 Signed-off-by: Patrick Wagstrom <160672+pridkett@users.noreply.github.com>
---
 server/docker.js | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/server/docker.js b/server/docker.js
index ee6051dfa..0d22f6542 100644
--- a/server/docker.js
+++ b/server/docker.js
@@ -156,15 +156,34 @@ class DockerHost {
         let certPath = path.join(Database.dockerTLSDir, dirName, DockerHost.CertificateFileNameCert);
         let keyPath = path.join(Database.dockerTLSDir, dirName, DockerHost.CertificateFileNameKey);
 
-        if (dockerType === "tcp" && fs.existsSync(caPath) && fs.existsSync(certPath) && fs.existsSync(keyPath)) {
-            let ca = fs.readFileSync(caPath);
-            let key = fs.readFileSync(keyPath);
-            let cert = fs.readFileSync(certPath);
-            certOptions = {
-                ca,
-                key,
-                cert
-            };
+        if (dockerType === "tcp") {
+            if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
+                // Load the key and cert
+                key = fs.readFileSync(keyPath);
+                cert = fs.readFileSync(certPath);
+
+                if (fs.existsSync(caPath)) {
+                    // Condition 1: Mutual TLS with self-signed certificate
+                    ca = fs.readFileSync(caPath);
+                    certOptions = {
+                        ca,
+                        key,
+                        cert
+                    };
+                } else {
+                    // Condition 2: Mutual TLS with certificate in the standard trust store
+                    certOptions = {
+                        key,
+                        cert
+                    };
+                }
+            } else if (fs.existsSync(caPath)) {
+                // Condition 3: TLS using self-signed certificate (without mutual TLS)
+                ca = fs.readFileSync(caPath);
+                certOptions = {
+                    ca
+                };
+            }
         }
 
         return {

From f65453e50c5b71e37545fdc506ee3d3637559432 Mon Sep 17 00:00:00 2001
From: Patrick Wagstrom <160672+pridkett@users.noreply.github.com>
Date: Sat, 21 Sep 2024 18:22:37 -0400
Subject: [PATCH 2/2] fix: correct linter errors

I missed some of the `let` definitions for the ca, cert, and key when
establishing the docker TLS connection.

DCO-1.1 Signed-off-by: Patrick Wagstrom <160672+pridkett@users.noreply.github.com>
---
 server/docker.js | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/server/docker.js b/server/docker.js
index 0d22f6542..8f3789c60 100644
--- a/server/docker.js
+++ b/server/docker.js
@@ -156,6 +156,10 @@ class DockerHost {
         let certPath = path.join(Database.dockerTLSDir, dirName, DockerHost.CertificateFileNameCert);
         let keyPath = path.join(Database.dockerTLSDir, dirName, DockerHost.CertificateFileNameKey);
 
+        let key;
+        let cert;
+        let ca;
+
         if (dockerType === "tcp") {
             if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
                 // Load the key and cert