[PATCHv2 1/5] virnetserver: Introduce virNetServerUpdateTlsFiles

Zhang Bo oscar.zhangbo at huawei.com
Sat Mar 7 11:31:00 UTC 2020


Add an API to update server's tls context.
---
 src/libvirt_remote.syms    |  1 +
 src/rpc/virnetserver.c     | 51 ++++++++++++++++++++++++++++++++++++++
 src/rpc/virnetserver.h     |  2 ++
 src/rpc/virnettlscontext.c | 46 ++++++++++++++++++++++++++++++++++
 src/rpc/virnettlscontext.h |  3 +++
 5 files changed, 103 insertions(+)

diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms
index 0493467f46..0018a0c41d 100644
--- a/src/libvirt_remote.syms
+++ b/src/libvirt_remote.syms
@@ -137,6 +137,7 @@ virNetServerSetClientLimits;
 virNetServerSetThreadPoolParameters;
 virNetServerSetTLSContext;
 virNetServerUpdateServices;
+virNetServerUpdateTlsFiles;
 
 
 # rpc/virnetserverclient.h
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 072ffdf5a3..0bfe94d3f8 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -21,6 +21,9 @@
 
 #include <config.h>
 
+#include <sys/types.h>
+#include <unistd.h>
+
 #include "virnetserver.h"
 #include "virlog.h"
 #include "viralloc.h"
@@ -1205,3 +1208,51 @@ virNetServerSetClientLimits(virNetServerPtr srv,
     virObjectUnlock(srv);
     return ret;
 }
+
+static virNetTLSContextPtr
+virNetServerGetTLSContext(virNetServerPtr srv)
+{
+    size_t i;
+    virNetTLSContextPtr ctxt = NULL;
+    virNetServerServicePtr svc = NULL;
+
+    /* find svcTLS from srv, get svcTLS->tls */
+    for (i = 0; i < srv->nservices; i++) {
+        svc = srv->services[i];
+        ctxt = virNetServerServiceGetTLSContext(svc);
+        if (ctxt != NULL)
+            break;
+    }
+
+    return ctxt;
+}
+
+int
+virNetServerUpdateTlsFiles(virNetServerPtr srv)
+{
+    int ret = -1;
+    virNetTLSContextPtr ctxt = NULL;
+    bool privileged = geteuid() == 0 ? true : false;
+
+    ctxt = virNetServerGetTLSContext(srv);
+    if (!ctxt) {
+        VIR_ERROR(_("no tls svc found, unable to update tls files"));
+        return -1;
+    }
+
+    virObjectLock(srv);
+    virObjectLock(ctxt);
+
+    if (virNetTLSContextReloadForServer(ctxt, !privileged)) {
+        VIR_ERROR(_("failed to reload server's tls context"));
+        goto cleanup;
+    }
+
+    VIR_INFO("update tls files success");
+    ret = 0;
+
+ cleanup:
+    virObjectUnlock(ctxt);
+    virObjectUnlock(srv);
+    return ret;
+}
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index 260c99b22d..1c6a2efb6c 100644
--- a/src/rpc/virnetserver.h
+++ b/src/rpc/virnetserver.h
@@ -133,3 +133,5 @@ size_t virNetServerGetCurrentUnauthClients(virNetServerPtr srv);
 int virNetServerSetClientLimits(virNetServerPtr srv,
                                 long long int maxClients,
                                 long long int maxClientsUnauth);
+
+int virNetServerUpdateTlsFiles(virNetServerPtr srv);
diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
index 44f0dfce77..02c17124a1 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -919,6 +919,52 @@ virNetTLSContextPtr virNetTLSContextNewServer(const char *cacert,
 }
 
 
+int virNetTLSContextReloadForServer(virNetTLSContextPtr ctxt,
+                                    bool tryUserPkiPath)
+{
+    gnutls_certificate_credentials_t x509credBak;
+    int err;
+    char *cacert = NULL;
+    char *cacrl = NULL;
+    char *cert = NULL;
+    char *key = NULL;
+
+    x509credBak = ctxt->x509cred;
+    ctxt->x509cred = NULL;
+
+    if (virNetTLSContextLocateCredentials(NULL, tryUserPkiPath, true,
+                                          &cacert, &cacrl, &cert, &key))
+        goto error;
+
+    err = gnutls_certificate_allocate_credentials(&ctxt->x509cred);
+    if (err) {
+        virReportError(VIR_ERR_SYSTEM_ERROR,
+                       _("Unable to allocate x509 credentials: %s"),
+                       gnutls_strerror(err));
+        goto error;
+    }
+
+    if (virNetTLSContextSanityCheckCredentials(true, cacert, cert))
+        goto error;
+
+    if (virNetTLSContextLoadCredentials(ctxt, true, cacert, cacrl, cert, key))
+        goto error;
+
+    gnutls_certificate_set_dh_params(ctxt->x509cred,
+                                     ctxt->dhParams);
+
+    gnutls_certificate_free_credentials(x509credBak);
+
+    return 0;
+
+ error:
+    if (ctxt->x509cred)
+        gnutls_certificate_free_credentials(ctxt->x509cred);
+    ctxt->x509cred = x509credBak;
+    return -1;
+}
+
+
 virNetTLSContextPtr virNetTLSContextNewClient(const char *cacert,
                                               const char *cacrl,
                                               const char *cert,
diff --git a/src/rpc/virnettlscontext.h b/src/rpc/virnettlscontext.h
index f3273bc26a..fe885aed9a 100644
--- a/src/rpc/virnettlscontext.h
+++ b/src/rpc/virnettlscontext.h
@@ -62,6 +62,9 @@ virNetTLSContextPtr virNetTLSContextNewClient(const char *cacert,
                                               bool sanityCheckCert,
                                               bool requireValidCert);
 
+int virNetTLSContextReloadForServer(virNetTLSContextPtr ctxt,
+                                    bool tryUserPkiPath);
+
 int virNetTLSContextCheckCertificate(virNetTLSContextPtr ctxt,
                                      virNetTLSSessionPtr sess);
 
-- 
2.23.0.windows.1






More information about the libvir-list mailing list