Blame SOURCES/0010-Explicitly-track-whether-x509-creds-have-been-set.patch

bf78cb
From 04a3fe9e8122166eb8f257396fd07314182d2fc2 Mon Sep 17 00:00:00 2001
bf78cb
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
bf78cb
Date: Wed, 31 Jan 2018 11:27:10 +0000
bf78cb
Subject: [PATCH] Explicitly track whether x509 creds have been set
bf78cb
MIME-Version: 1.0
bf78cb
Content-Type: text/plain; charset=UTF-8
bf78cb
Content-Transfer-Encoding: 8bit
bf78cb
bf78cb
If we want to use the system trust DB, we can't rely on cred_x509_cacert
bf78cb
field being non-NULL. We must explicitly record whether the client app
bf78cb
has set the x509 credentials. We allow cacert to be missing if we are
bf78cb
built against a new enough GNUTLS.
bf78cb
bf78cb
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
bf78cb
(cherry picked from commit abc27748c6ca309ec3c39fb6c84426a459f56c74)
bf78cb
---
bf78cb
 src/vncconnection.c | 21 ++++++++++++++++++---
bf78cb
 1 file changed, 18 insertions(+), 3 deletions(-)
bf78cb
bf78cb
diff --git a/src/vncconnection.c b/src/vncconnection.c
bf78cb
index 35966c9..7fcbe89 100644
bf78cb
--- a/src/vncconnection.c
bf78cb
+++ b/src/vncconnection.c
bf78cb
@@ -217,6 +217,7 @@ struct _VncConnectionPrivate
bf78cb
     char *cred_x509_cacrl;
bf78cb
     char *cred_x509_cert;
bf78cb
     char *cred_x509_key;
bf78cb
+    gboolean set_cred_x509;
bf78cb
     gboolean want_cred_username;
bf78cb
     gboolean want_cred_password;
bf78cb
     gboolean want_cred_x509;
bf78cb
@@ -3528,7 +3529,7 @@ static gboolean vnc_connection_has_credentials(gpointer data)
bf78cb
         return FALSE;
bf78cb
     if (priv->want_cred_password && !priv->cred_password)
bf78cb
         return FALSE;
bf78cb
-    if (priv->want_cred_x509 && !priv->cred_x509_cacert)
bf78cb
+    if (priv->want_cred_x509 && !priv->set_cred_x509)
bf78cb
         return FALSE;
bf78cb
     return TRUE;
bf78cb
 }
bf78cb
@@ -5122,6 +5123,7 @@ static void vnc_connection_close(VncConnection *conn)
bf78cb
         priv->cred_password = NULL;
bf78cb
     }
bf78cb
 
bf78cb
+    priv->set_cred_x509 = FALSE;
bf78cb
     if (priv->cred_x509_cacert) {
bf78cb
         g_free(priv->cred_x509_cacert);
bf78cb
         priv->cred_x509_cacert = NULL;
bf78cb
@@ -5838,6 +5840,7 @@ static gboolean vnc_connection_set_credential_x509(VncConnection *conn,
bf78cb
 {
bf78cb
     VncConnectionPrivate *priv = conn->priv;
bf78cb
     char *sysdir = g_strdup_printf("%s/pki", SYSCONFDIR);
bf78cb
+    int ret;
bf78cb
 #ifndef WIN32
bf78cb
     struct passwd *pw;
bf78cb
 
bf78cb
@@ -5852,9 +5855,19 @@ static gboolean vnc_connection_set_credential_x509(VncConnection *conn,
bf78cb
     for (int i = 0 ; i < sizeof(dirs)/sizeof(dirs[0]) ; i++)
bf78cb
         VNC_DEBUG("Searching for certs in %s", dirs[i]);
bf78cb
 
bf78cb
-    if (vnc_connection_best_path(&priv->cred_x509_cacert, "CA", "cacert.pem",
bf78cb
-                                 dirs, sizeof(dirs)/sizeof(dirs[0])) < 0)
bf78cb
+    ret = vnc_connection_best_path(&priv->cred_x509_cacert, "CA", "cacert.pem",
bf78cb
+                                   dirs, sizeof(dirs)/sizeof(dirs[0]));
bf78cb
+    /* With modern GNUTLS we can just allow the global GNUTLS trust database
bf78cb
+     * to be used to validate CA certificates if no specific cert is set
bf78cb
+     */
bf78cb
+    if (ret < 0) {
bf78cb
+#if GNUTLS_VERSION_NUMBER < 0x030000
bf78cb
+        VNC_DEBUG("No CA certificate provided and no global fallback");
bf78cb
         return FALSE;
bf78cb
+#else
bf78cb
+        VNC_DEBUG("No CA certificate provided, using GNUTLS global trust");
bf78cb
+#endif
bf78cb
+    }
bf78cb
 
bf78cb
     /* Don't mind failures of CRL */
bf78cb
     vnc_connection_best_path(&priv->cred_x509_cacrl, "CA", "cacrl.pem",
bf78cb
@@ -5867,6 +5880,8 @@ static gboolean vnc_connection_set_credential_x509(VncConnection *conn,
bf78cb
     vnc_connection_best_path(&priv->cred_x509_cert, name, "clientcert.pem",
bf78cb
                              dirs, sizeof(dirs)/sizeof(dirs[0]));
bf78cb
 
bf78cb
+    priv->set_cred_x509 = TRUE;
bf78cb
+
bf78cb
     return TRUE;
bf78cb
 }
bf78cb