Enable TLS-PSK based secure migration, if and only if both source and
destination supports the tls-creds-psk object.

Suggested-by: Tejus GK <[email protected]>
Signed-off-by: Abhisek Panda <[email protected]>
---
 include/libvirt/libvirt-domain.h | 10 ++++--
 src/qemu/qemu_migration.c        | 56 ++++++++++++++++++++++++--------
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 99208137c3..2ec3956f8b 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1089,9 +1089,13 @@ typedef enum {
     VIR_MIGRATE_POSTCOPY = (1 << 15),
 
     /* Setting the VIR_MIGRATE_TLS flag will cause the migration to attempt
-     * to use the TLS environment configured by the hypervisor in order to
-     * perform the migration. If incorrectly configured on either source or
-     * destination, the migration will fail.
+     * to use the TLS X.509 authentication mechanisms only if the TLS 
pre-shared
+     * key (PSK) authentication mechanism is not supported by either source
+     * or destination. If the certificate or the key files are incorrectly 
configured
+     * on either source or destination, then the migration will fail.
+     *
+     * Note: Since 12.7.0, Libvirt supports the TLS pre-shared key (PSK) 
authentication
+     * mechanism along with the TLS X.509 authentication scheme.
      *
      * Since: 3.2.0
      */
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 2fc8af9c15..e9c8ddc343 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3499,9 +3499,19 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver,
     /* Save original migration parameters */
     qemuDomainSaveStatus(vm);
 
-    /* Migrations using TLS need to add the "tls-creds-x509" object and
-     * set the migration TLS parameters */
-    if (flags & VIR_MIGRATE_TLS) {
+    /* Migrations need to add the "tls-creds-psk" object whenever both
+     * sides support TLS-PSK authentication regardless of the
+     * VIR_MIGRATE_TLS flag. Otherwise, fall back to "tls-creds-x509" if
+     * VIR_MIGRATE_TLS is enabled. Finally, set the appropriate migration
+     * TLS parameters. */
+    if ((mig->flags & QEMU_MIGRATION_COOKIE_TLS_PSK) && mig->tlsPSK) {
+        if (qemuMigrationPersistPSK(driver, vm, mig->tlsPSK) < 0)
+            goto error;
+        if (qemuMigrationParamsEnableTLSPSK(driver, vm, true,
+                                            VIR_ASYNC_JOB_MIGRATION_IN,
+                                            &tlsAlias, migParams) < 0)
+            goto error;
+    } else if (flags & VIR_MIGRATE_TLS) {
         if (qemuMigrationParamsEnableTLSx509(driver, vm, true,
                                              VIR_ASYNC_JOB_MIGRATION_IN,
                                              &tlsAlias, NULL,
@@ -3516,14 +3526,13 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver,
         flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)) {
         const char *nbdTLSAlias = NULL;
 
-        if (flags & VIR_MIGRATE_TLS) {
-            if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) {
-                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-                               _("QEMU NBD server does not support TLS 
transport"));
-                goto error;
-            }
-
+        if (tlsAlias && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) {
             nbdTLSAlias = tlsAlias;
+        } else if ((flags & VIR_MIGRATE_TLS) &&
+                   !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) {
+            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                           _("QEMU NBD server does not support TLS 
transport"));
+            goto error;
         }
 
         if (qemuMigrationDstStartNBDServer(driver, vm, incoming->address,
@@ -3611,7 +3620,7 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver,
     qemuDomainObjPrivate *priv = NULL;
     g_autoptr(qemuMigrationCookie) mig = NULL;
     g_autofree char *xmlout = NULL;
-    unsigned int cookieFlags = 0;
+    unsigned int cookieFlags = QEMU_MIGRATION_COOKIE_TLS_PSK;
     bool taint_hook = false;
 
     VIR_DEBUG("name=%s, origname=%s, protocol=%s, port=%hu, "
@@ -3677,7 +3686,8 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver,
                                          QEMU_MIGRATION_COOKIE_CPU_HOTPLUG |
                                          QEMU_MIGRATION_COOKIE_CPU |
                                          QEMU_MIGRATION_COOKIE_CAPS |
-                                         
QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS)))
+                                         
QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS |
+                                         QEMU_MIGRATION_COOKIE_TLS_PSK)))
         goto cleanup;
 
     if (!(vm = virDomainObjListAdd(driver->domains, def,
@@ -5102,6 +5112,9 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
     if (storageMigration)
         cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
 
+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_TLS_CREDS_PSK))
+        cookieFlags |= QEMU_MIGRATION_COOKIE_TLS_PSK;
+
     if (virLockManagerPluginUsesState(driver->lockManager) &&
         !cookieout) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -5152,7 +5165,12 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
     /* Save original migration parameters */
     qemuDomainSaveStatus(vm);
 
-    if (flags & VIR_MIGRATE_TLS) {
+    if (mig->flags & QEMU_MIGRATION_COOKIE_TLS_PSK) {
+        if (qemuMigrationParamsEnableTLSPSK(driver, vm, false,
+                                            VIR_ASYNC_JOB_MIGRATION_OUT,
+                                            &tlsAlias, migParams) < 0)
+            goto error;
+    } else if (flags & VIR_MIGRATE_TLS) {
         const char *hostname = NULL;
 
         /* We need to add tls-hostname whenever QEMU itself does not
@@ -5201,6 +5219,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
     if (storageMigration) {
         const char *host = "";
         const char *tlsHostname = qemuMigrationParamsGetTLSHostname(migParams);
+        const char *nbdTLSAlias = NULL;
 
         if (!mig->nbd) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -5213,13 +5232,22 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
             host = spec->dest.host.name;
         }
 
+        if (tlsAlias && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) {
+            nbdTLSAlias = tlsAlias;
+        } else if ((flags & VIR_MIGRATE_TLS) &&
+                   !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) {
+            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                           _("QEMU NBD client does not support TLS 
transport"));
+            goto error;
+        }
+
         if (qemuMigrationSrcNBDStorageCopy(driver, vm, mig,
                                            host,
                                            priv->migMaxBandwidth,
                                            migrate_disks,
                                            migrate_disks_detect_zeroes,
                                            migrate_disks_target_zero,
-                                           dconn, tlsAlias, tlsHostname,
+                                           dconn, nbdTLSAlias, tlsHostname,
                                            nbdURI, flags) < 0) {
             goto error;
         }
-- 
2.43.7

Reply via email to