Re: [PATCH 4/6] admin: support server cert update mode

2020-02-11 Thread Daniel P . Berrangé
On Sun, Feb 09, 2020 at 10:03:14PM +0800, Zhang Bo wrote:
> virAdmServerUpdateTlsFiles:
> @flags specifies how to update server cert/key in tls service.
> Two modes are currently supported: append mode and clear mode, means
> whether to clear the original cert then add the new one, or just append
> to the original one.
> ---
>  include/libvirt/libvirt-admin.h | 14 ++
>  src/admin/admin_server.c|  7 +--
>  src/admin/libvirt-admin.c   |  7 ++-
>  src/rpc/virnetserver.c  | 17 +
>  src/rpc/virnetserver.h  |  3 ++-
>  src/rpc/virnettlscontext.c  |  7 +--
>  src/rpc/virnettlscontext.h  |  3 ++-
>  7 files changed, 43 insertions(+), 15 deletions(-)
> 
> diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h
> index 6e38261129..dfdd81ae83 100644
> --- a/include/libvirt/libvirt-admin.h
> +++ b/include/libvirt/libvirt-admin.h
> @@ -392,6 +392,20 @@ int virAdmClientClose(virAdmClientPtr client, unsigned 
> int flags);
>  
>  # define VIR_SERVER_CLIENTS_UNAUTH_CURRENT "nclients_unauth"
>  
> +typedef enum {
> +/* free old credentials and then set new tls context.
> + */
> +VIR_TLS_UPDATE_CLEAR  = 0,
> +
> +/* do not clear original certificates and keys.
> + */
> +VIR_TLS_UPDATE_APPEND = 1,

I don't think we should we supporting this operation. In order to achieve
reliability of the TLS reload, we need to re-create the credentials object
and swap out the original credentails on success. This precludes updating
the original credentials

> @@ -1165,7 +1166,9 @@ int virNetTLSContextReload(virNetTLSContextPtr ctxt,
>  }
>  
>  if (filetypes & VIR_TLS_FILE_TYPE_SERVER_CERT) {
> -gnutls_certificate_free_keys(ctxt->x509cred);
> +if (flags == VIR_TLS_UPDATE_CLEAR)
> +gnutls_certificate_free_keys(ctxt->x509cred);
> +
>  if (virNetTLSContextSetCertAndKey(ctxt, cert, key, false))
>  goto cleanup;

...because this code still has the dangerous behaviour that it leaves the
server without any valid cert/key on failure.

The second bad thing is that the state in-memory does not match the
state on disk. This puts the old & new cert+key in memory, but only
the new cert+key is on disk. So if libvirtd is restarted for any
reason you'll get a change in certs again. The reload operation
should just be updating libvirtd's in-memory state to exactly match
the on-disk state, in the same way that a restart does.


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 :|



撤回: [PATCH 4/6] admin: support server cert update mode

2020-02-09 Thread Zhangbo (Oscar)
Zhangbo (Oscar) 将撤回邮件“[PATCH 4/6] admin: support server cert update mode”。



[PATCH 4/6] admin: support server cert update mode

2020-02-09 Thread Zhang Bo
virAdmServerUpdateTlsFiles:
@flags specifies how to update server cert/key in tls service.
Two modes are currently supported: append mode and clear mode, means
whether to clear the original cert then add the new one, or just append
to the original one.
---
 include/libvirt/libvirt-admin.h | 14 ++
 src/admin/admin_server.c|  7 +--
 src/admin/libvirt-admin.c   |  7 ++-
 src/rpc/virnetserver.c  | 17 +
 src/rpc/virnetserver.h  |  3 ++-
 src/rpc/virnettlscontext.c  |  7 +--
 src/rpc/virnettlscontext.h  |  3 ++-
 7 files changed, 43 insertions(+), 15 deletions(-)

diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h
index 6e38261129..dfdd81ae83 100644
--- a/include/libvirt/libvirt-admin.h
+++ b/include/libvirt/libvirt-admin.h
@@ -392,6 +392,20 @@ int virAdmClientClose(virAdmClientPtr client, unsigned int 
flags);
 
 # define VIR_SERVER_CLIENTS_UNAUTH_CURRENT "nclients_unauth"
 
+typedef enum {
+/* free old credentials and then set new tls context.
+ */
+VIR_TLS_UPDATE_CLEAR  = 0,
+
+/* do not clear original certificates and keys.
+ */
+VIR_TLS_UPDATE_APPEND = 1,
+
+/* boundary value for flag check (unreachable).
+ */
+VIR_TLS_UPDATE_FLAG_MAX   = 2,
+} virServerTlsUpdateFlag;
+
 /* tls related filetype flags. */
 typedef enum {
 VIR_TLS_FILE_TYPE_CA_CERT = (1U << 0),
diff --git a/src/admin/admin_server.c b/src/admin/admin_server.c
index 558913367b..43c7e00d90 100644
--- a/src/admin/admin_server.c
+++ b/src/admin/admin_server.c
@@ -373,10 +373,5 @@ adminServerUpdateTlsFiles(virNetServerPtr srv,
   unsigned int filetypes,
   unsigned int flags)
 {
-virCheckFlags(0, -1);
-
-if (virNetServerUpdateTlsFiles(srv, filetypes) < 0)
-return -1;
-
-return 0;
+return virNetServerUpdateTlsFiles(srv, filetypes, flags);
 }
diff --git a/src/admin/libvirt-admin.c b/src/admin/libvirt-admin.c
index f3f92ed91c..b6ba72b577 100644
--- a/src/admin/libvirt-admin.c
+++ b/src/admin/libvirt-admin.c
@@ -1086,12 +1086,17 @@ virAdmServerSetClientLimits(virAdmServerPtr srv,
  * virAdmServerUpdateTlsFiles:
  * @srv: a valid server object reference
  * @filetypes: bitwise-OR of virServerTlsFiletype
- * @flags: extra flags; not used yet, so callers should always pass 0
+ * @flags: mode that specifies the update method
  *
  * Notify server to update tls file, such as cacert, cacrl, server cert / key.
  * Mark the files that need to be updated by the @filetypes parameter.
  * See virServerTlsFiletype for detailed description of accepted filetypes.
  *
+ * @flags specifies how to update server cert/key in tls service,
+ * and is either the value VIR_TLS_UPDATE_APPEND, or VIR_TLS_UPDATE_CLEAR.
+ * The default value is VIR_TLS_UPDATE_CLEAR. See virServerTlsUpdateFlag for
+ * detailed description.
+ *
  * Returns 0 if the TLS files have been updated successfully or -1 in case of 
an
  * error.
  */
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 65ec677d0a..72c4d37bc6 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -1226,7 +1226,8 @@ virNetServerGetTLSContext(virNetServerPtr srv)
 return ctxt;
 }
 
-static int virNetServerUpdateTlsFilesCheckParams(unsigned int filetypes)
+static int virNetServerUpdateTlsFilesCheckParams(unsigned int filetypes,
+ unsigned int flags)
 {
 bool haveSrvCert = filetypes & VIR_TLS_FILE_TYPE_SERVER_CERT;
 bool haveSrvKey = filetypes & VIR_TLS_FILE_TYPE_SERVER_KEY;
@@ -1239,12 +1240,20 @@ static int 
virNetServerUpdateTlsFilesCheckParams(unsigned int filetypes)
 return -1;
 }
 
+if (flags >= VIR_TLS_UPDATE_FLAG_MAX) {
+virReportError(VIR_ERR_SYSTEM_ERROR,
+   _("don not support flags: %d"),
+   flags);
+return -1;
+}
+
 return 0;
 }
 
 int
 virNetServerUpdateTlsFiles(virNetServerPtr srv,
-   unsigned int filetypes)
+   unsigned int filetypes,
+   unsigned int flags)
 {
 int ret = -1;
 #ifndef WITH_GNUTLS
@@ -1254,7 +1263,7 @@ virNetServerUpdateTlsFiles(virNetServerPtr srv,
 #else
 virNetTLSContextPtr ctxt = NULL;
 
-if (virNetServerUpdateTlsFilesCheckParams(filetypes))
+if (virNetServerUpdateTlsFilesCheckParams(filetypes, flags))
 return -1;
 
 virObjectLock(srv);
@@ -1266,7 +1275,7 @@ virNetServerUpdateTlsFiles(virNetServerPtr srv,
 goto cleanup;
 }
 
-if (virNetTLSContextReload(ctxt, filetypes)) {
+if (virNetTLSContextReload(ctxt, filetypes, flags)) {
 VIR_ERROR(_("reload server's tls context fail"));
 goto cleanup;
 }
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index 99466dd041..1a905aa483 100644
--- a/src/rpc/virnetserver.h
+++ b

[PATCH 4/6] admin: support server cert update mode

2020-02-09 Thread Zhangbo (Oscar)
virAdmServerUpdateTlsFiles:
@flags specifies how to update server cert/key in tls service.
Two modes are currently supported: append mode and clear mode, means
whether to clear the original cert then add the new one, or just append
to the original one.
---
 include/libvirt/libvirt-admin.h | 14 ++
 src/admin/admin_server.c|  7 +--
 src/admin/libvirt-admin.c   |  7 ++-
 src/rpc/virnetserver.c  | 17 +
 src/rpc/virnetserver.h  |  3 ++-
 src/rpc/virnettlscontext.c  |  7 +--
 src/rpc/virnettlscontext.h  |  3 ++-
 7 files changed, 43 insertions(+), 15 deletions(-)

diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h
index 6e38261129..dfdd81ae83 100644
--- a/include/libvirt/libvirt-admin.h
+++ b/include/libvirt/libvirt-admin.h
@@ -392,6 +392,20 @@ int virAdmClientClose(virAdmClientPtr client, unsigned int 
flags);

 # define VIR_SERVER_CLIENTS_UNAUTH_CURRENT "nclients_unauth"

+typedef enum {
+/* free old credentials and then set new tls context.
+ */
+VIR_TLS_UPDATE_CLEAR  = 0,
+
+/* do not clear original certificates and keys.
+ */
+VIR_TLS_UPDATE_APPEND = 1,
+
+/* boundary value for flag check (unreachable).
+ */
+VIR_TLS_UPDATE_FLAG_MAX   = 2,
+} virServerTlsUpdateFlag;
+
 /* tls related filetype flags. */
 typedef enum {
 VIR_TLS_FILE_TYPE_CA_CERT = (1U << 0),
diff --git a/src/admin/admin_server.c b/src/admin/admin_server.c
index 558913367b..43c7e00d90 100644
--- a/src/admin/admin_server.c
+++ b/src/admin/admin_server.c
@@ -373,10 +373,5 @@ adminServerUpdateTlsFiles(virNetServerPtr srv,
   unsigned int filetypes,
   unsigned int flags)
 {
-virCheckFlags(0, -1);
-
-if (virNetServerUpdateTlsFiles(srv, filetypes) < 0)
-return -1;
-
-return 0;
+return virNetServerUpdateTlsFiles(srv, filetypes, flags);
 }
diff --git a/src/admin/libvirt-admin.c b/src/admin/libvirt-admin.c
index f3f92ed91c..b6ba72b577 100644
--- a/src/admin/libvirt-admin.c
+++ b/src/admin/libvirt-admin.c
@@ -1086,12 +1086,17 @@ virAdmServerSetClientLimits(virAdmServerPtr srv,
  * virAdmServerUpdateTlsFiles:
  * @srv: a valid server object reference
  * @filetypes: bitwise-OR of virServerTlsFiletype
- * @flags: extra flags; not used yet, so callers should always pass 0
+ * @flags: mode that specifies the update method
  *
  * Notify server to update tls file, such as cacert, cacrl, server cert / key.
  * Mark the files that need to be updated by the @filetypes parameter.
  * See virServerTlsFiletype for detailed description of accepted filetypes.
  *
+ * @flags specifies how to update server cert/key in tls service,
+ * and is either the value VIR_TLS_UPDATE_APPEND, or VIR_TLS_UPDATE_CLEAR.
+ * The default value is VIR_TLS_UPDATE_CLEAR. See virServerTlsUpdateFlag for
+ * detailed description.
+ *
  * Returns 0 if the TLS files have been updated successfully or -1 in case of 
an
  * error.
  */
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 65ec677d0a..72c4d37bc6 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -1226,7 +1226,8 @@ virNetServerGetTLSContext(virNetServerPtr srv)
 return ctxt;
 }

-static int virNetServerUpdateTlsFilesCheckParams(unsigned int filetypes)
+static int virNetServerUpdateTlsFilesCheckParams(unsigned int filetypes,
+ unsigned int flags)
 {
 bool haveSrvCert = filetypes & VIR_TLS_FILE_TYPE_SERVER_CERT;
 bool haveSrvKey = filetypes & VIR_TLS_FILE_TYPE_SERVER_KEY;
@@ -1239,12 +1240,20 @@ static int 
virNetServerUpdateTlsFilesCheckParams(unsigned int filetypes)
 return -1;
 }

+if (flags >= VIR_TLS_UPDATE_FLAG_MAX) {
+virReportError(VIR_ERR_SYSTEM_ERROR,
+   _("don not support flags: %d"),
+   flags);
+return -1;
+}
+
 return 0;
 }

 int
 virNetServerUpdateTlsFiles(virNetServerPtr srv,
-   unsigned int filetypes)
+   unsigned int filetypes,
+   unsigned int flags)
 {
 int ret = -1;
 #ifndef WITH_GNUTLS
@@ -1254,7 +1263,7 @@ virNetServerUpdateTlsFiles(virNetServerPtr srv,
 #else
 virNetTLSContextPtr ctxt = NULL;

-if (virNetServerUpdateTlsFilesCheckParams(filetypes))
+if (virNetServerUpdateTlsFilesCheckParams(filetypes, flags))
 return -1;

 virObjectLock(srv);
@@ -1266,7 +1275,7 @@ virNetServerUpdateTlsFiles(virNetServerPtr srv,
 goto cleanup;
 }

-if (virNetTLSContextReload(ctxt, filetypes)) {
+if (virNetTLSContextReload(ctxt, filetypes, flags)) {
 VIR_ERROR(_("reload server's tls context fail"));
 goto cleanup;
 }
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index 99466dd041..1a905aa483 100644
--- a/src/rpc/virnetserver.h
+++ b/src/rpc