Enable TLS-PSK based secure migration at the source and destination,
if and only if the VIR_MIGRATE_TLS_PSK flag is set. To prevent
configuration conflicts, report an error in case a user attempts to
enable both TLS-PSK and TLS x509 certificate authentication methods
simultaneously.

Suggested-by: Tejus GK <[email protected]>
Signed-off-by: Abhisek Panda <[email protected]>
---
 src/qemu/qemu.conf.in     |   8 +--
 src/qemu/qemu_migration.c | 110 +++++++++++++++++++++++++++-----------
 2 files changed, 82 insertions(+), 36 deletions(-)

diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in
index 5dfd3229e5..fa4f711592 100644
--- a/src/qemu/qemu.conf.in
+++ b/src/qemu/qemu.conf.in
@@ -440,10 +440,10 @@
 #migrate_tls_priority = "@SYSTEM"
 
 
-# By default TLS is requested using the VIR_MIGRATE_TLS flag, thus not 
requested
-# automatically. Setting 'migate_tls_force' to "1" will prevent any migration
-# which is not using VIR_MIGRATE_TLS to ensure higher level of security in
-# deployments with TLS.
+# By default TLS is requested using either VIR_MIGRATE_TLS or 
VIR_MIGRATE_TLS_PSK
+# flags, thus not requested automatically. Setting 'migate_tls_force' to "1" 
will
+# prevent any migration which is not using either VIR_MIGRATE_TLS or 
VIR_MIGRATE_TLS_PSK
+# to ensure higher level of security in deployments with TLS.
 #
 #migrate_tls_force = 0
 
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 15e3571c99..239d547bb0 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3078,9 +3078,9 @@ qemuMigrationSrcBegin(virConnectPtr conn,
 
     if (cfg->migrateTLSForce &&
         !(flags & VIR_MIGRATE_TUNNELLED) &&
-        !(flags & VIR_MIGRATE_TLS)) {
+        !(flags & (VIR_MIGRATE_TLS | VIR_MIGRATE_TLS_PSK))) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-                       _("this libvirtd instance allows migration only with 
VIR_MIGRATE_TLS flag"));
+                       _("this libvirtd instance allows migration only with 
VIR_MIGRATE_TLS or VIR_MIGRATE_TLS_PSK flags"));
         goto cleanup;
     }
 
@@ -3327,6 +3327,7 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver,
     qemuDomainJobPrivate *jobPriv = vm->job->privateData;
     qemuProcessIncomingDef *incoming = NULL;
     g_autofree char *tlsx509Alias = NULL;
+    g_autofree char *tlsPSKAlias = NULL;
     virObjectEvent *event = NULL;
     virErrorPtr origErr = NULL;
     int dataFD[2] = { -1, -1 };
@@ -3335,6 +3336,7 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver,
     bool relabel = false;
     bool tunnel = !!st;
     int ret = -1;
+    int tls_creds_type = 0;
     int rv;
 
     if (STREQ_NULLABLE(protocol, "rdma") &&
@@ -3409,17 +3411,36 @@ 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) {
-        if (qemuMigrationParamsEnableTLSx509(driver, vm, true,
-                                             VIR_ASYNC_JOB_MIGRATION_IN,
-                                             &tlsx509Alias, NULL,
-                                             migParams) < 0)
-            goto error;
-    } else {
-        if (qemuMigrationParamsDisableTLS(vm, migParams) < 0)
+    /* Migrations using TLS can support two types of credential
+     * objects: "tls-creds-x509" and "tls-creds-psk". Set the migration
+     * TLS parameters based on the chosen credential type.
+     */
+    tls_creds_type = flags & (VIR_MIGRATE_TLS | VIR_MIGRATE_TLS_PSK);
+    switch (tls_creds_type) {
+        case 0:
+            if (qemuMigrationParamsDisableTLS(vm, migParams) < 0)
+                goto error;
+            break;
+        case VIR_MIGRATE_TLS:
+            if (qemuMigrationParamsEnableTLSx509(driver, vm, true,
+                                                 VIR_ASYNC_JOB_MIGRATION_IN,
+                                                 &tlsx509Alias, NULL,
+                                                 migParams) < 0)
+                goto error;
+            break;
+        case VIR_MIGRATE_TLS_PSK:
+            if (qemuMigrationParamsEnableTLSPSK(driver, vm, true,
+                                                VIR_ASYNC_JOB_MIGRATION_IN,
+                                                &tlsPSKAlias, NULL,
+                                                migParams) < 0)
+                goto error;
+            break;
+        case VIR_MIGRATE_TLS | VIR_MIGRATE_TLS_PSK:
+            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+            _("Both TLS x509 and TLS PSK are enabled simultaneously"));
             goto error;
+        default:
+            break;
     }
 
     if (mig->nbd &&
@@ -3825,9 +3846,9 @@ qemuMigrationDstPrepareAny(virQEMUDriver *driver,
 
     if (cfg->migrateTLSForce &&
         !(flags & VIR_MIGRATE_TUNNELLED) &&
-        !(flags & VIR_MIGRATE_TLS)) {
+        !(flags & (VIR_MIGRATE_TLS | VIR_MIGRATE_TLS_PSK))) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-                       _("this libvirtd instance allows migration only with 
VIR_MIGRATE_TLS flag"));
+                       _("this libvirtd instance allows migration only with 
VIR_MIGRATE_TLS or VIR_MIGRATE_TLS_PSK flags"));
         return -1;
     }
 
@@ -4978,6 +4999,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
     qemuDomainObjPrivate *priv = vm->privateData;
     g_autoptr(qemuMigrationCookie) mig = NULL;
     g_autofree char *tlsx509Alias = NULL;
+    g_autofree char *tlsPSKAlias = NULL;
     qemuMigrationIOThread *iothread = NULL;
     VIR_AUTOCLOSE fd = -1;
     unsigned long restore_max_bandwidth = priv->migMaxBandwidth;
@@ -4988,6 +5010,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
     bool cancel = false;
     unsigned int waitFlags;
     g_autoptr(virDomainDef) persistDef = NULL;
+    int tls_creds_type = 0;
     int rc;
 
     if (bandwidth > 0)
@@ -5061,23 +5084,46 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
     /* Save original migration parameters */
     qemuDomainSaveStatus(vm);
 
-    if (flags & VIR_MIGRATE_TLS) {
-        const char *hostname = NULL;
-
-        /* We need to add tls-hostname whenever QEMU itself does not
-         * connect directly to the destination. */
-        if (spec->destType == MIGRATION_DEST_CONNECT_HOST ||
-            spec->destType == MIGRATION_DEST_FD)
-            hostname = spec->dest.host.name;
-
-        if (qemuMigrationParamsEnableTLSx509(driver, vm, false,
-                                             VIR_ASYNC_JOB_MIGRATION_OUT,
-                                             &tlsx509Alias, hostname,
-                                             migParams) < 0)
-            goto error;
-    } else {
-        if (qemuMigrationParamsDisableTLS(vm, migParams) < 0)
+    /* Migrations using TLS can support two types of credential
+     * objects: "tls-creds-x509" and "tls-creds-psk". Set the migration
+     * TLS parameters based on the chosen credential type.
+     */
+    tls_creds_type = flags & (VIR_MIGRATE_TLS | VIR_MIGRATE_TLS_PSK);
+    switch (tls_creds_type) {
+        case 0:
+            if (qemuMigrationParamsDisableTLS(vm, migParams) < 0)
+                goto error;
+            break;
+        case VIR_MIGRATE_TLS:{
+            const char *hostname = NULL;
+
+            /* We need to add tls-hostname whenever QEMU itself does not
+            * connect directly to the destination. */
+            if (spec->destType == MIGRATION_DEST_CONNECT_HOST ||
+                spec->destType == MIGRATION_DEST_FD)
+                hostname = spec->dest.host.name;
+
+            if (qemuMigrationParamsEnableTLSx509(driver, vm, false,
+                                                 VIR_ASYNC_JOB_MIGRATION_OUT,
+                                                 &tlsx509Alias, hostname,
+                                                 migParams) < 0)
+                goto error;
+            break;
+        }
+        case VIR_MIGRATE_TLS_PSK: {
+            if (qemuMigrationParamsEnableTLSPSK(driver, vm, false,
+                                                VIR_ASYNC_JOB_MIGRATION_OUT,
+                                                &tlsPSKAlias, 
spec->dest.host.username,
+                                                migParams) < 0)
+                goto error;
+            break;
+        }
+        case VIR_MIGRATE_TLS|VIR_MIGRATE_TLS_PSK:
+            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+            _("Both TLS and TLS-PSK are enabled simultaneously"));
             goto error;
+        default:
+            break;
     }
 
     if (qemuMigrationParamsSetULL(migParams, 
QEMU_MIGRATION_PARAM_MAX_BANDWIDTH,
@@ -6553,9 +6599,9 @@ qemuMigrationSrcPerform(virQEMUDriver *driver,
 
     if (cfg->migrateTLSForce &&
         !(flags & VIR_MIGRATE_TUNNELLED) &&
-        !(flags & VIR_MIGRATE_TLS)) {
+        !(flags & (VIR_MIGRATE_TLS | VIR_MIGRATE_TLS_PSK))) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-                       _("this libvirtd instance allows migration only with 
VIR_MIGRATE_TLS flag"));
+                       _("this libvirtd instance allows migration only with 
VIR_MIGRATE_TLS or VIR_MIGRATE_TLS_PSK flags"));
         return -1;
     }
 
-- 
2.39.3

Reply via email to