[PATCHv2 1/5] virnetserver: Introduce virNetServerUpdateTlsFiles

Zhang Bo posted 5 patches 5 years, 11 months ago
[PATCHv2 1/5] virnetserver: Introduce virNetServerUpdateTlsFiles
Posted by Zhang Bo 5 years, 11 months ago
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



Re: [PATCHv2 1/5] virnetserver: Introduce virNetServerUpdateTlsFiles
Posted by Daniel P. Berrangé 5 years, 11 months ago
On Sat, Mar 07, 2020 at 07:31:00PM +0800, Zhang Bo wrote:
> 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>

We use  virutil.h for geteuid() definition.

> +
>  #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"));

Should be a virReportError

> +        return -1;
> +    }
> +
> +    virObjectLock(srv);
> +    virObjectLock(ctxt);
> +
> +    if (virNetTLSContextReloadForServer(ctxt, !privileged)) {
> +        VIR_ERROR(_("failed to reload server's tls context"));

VIR_DEBUG is sufficient

> +        goto cleanup;
> +    }
> +
> +    VIR_INFO("update tls files success");
> +    ret = 0;
> +
> + cleanup:
> +    virObjectUnlock(ctxt);
> +    virObjectUnlock(srv);
> +    return ret;
> +}


Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|