To enable TLS-PSK-based authentication scheme, add support for
instantiating the tls-creds-psk object through QEMU monitor. In order
to remove the TLS-related objects from a QEMU instance, augment the
qemuDomainDelTLSObjects handler to also consider the TLS-PSK object.

Suggested-by: Tejus GK <[email protected]>
Signed-off-by: Abhisek Panda <[email protected]>
---
 src/qemu/qemu_alias.c            | 11 +++++
 src/qemu/qemu_alias.h            |  3 ++
 src/qemu/qemu_hotplug.c          | 59 +++++++++++++++++++++++---
 src/qemu/qemu_hotplug.h          | 15 ++++++-
 src/qemu/qemu_migration_params.c | 73 ++++++++++++++++++++++++++++++--
 src/qemu/qemu_migration_params.h |  9 ++++
 6 files changed, 159 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c
index 9133389df1..4d61d7d2fe 100644
--- a/src/qemu/qemu_alias.c
+++ b/src/qemu/qemu_alias.c
@@ -883,6 +883,17 @@ qemuAliasTLSx509ObjFromSrcAlias(const char *srcAlias)
     return g_strdup_printf("obj%s_tlsx5090", srcAlias);
 }
 
+/* qemuAliasTLSPSKObjFromSrcAlias
+ * @srcAlias: Pointer to a source alias string
+ *
+ * Generate and return a string to be used as the TLS PSK object alias
+ */
+char *
+qemuAliasTLSPSKObjFromSrcAlias(const char *srcAlias)
+{
+    return g_strdup_printf("obj%s_tlspsk0", srcAlias);
+}
+
 
 /* qemuAliasChardevFromDevAlias:
  * @devAlias: pointer do device alias
diff --git a/src/qemu/qemu_alias.h b/src/qemu/qemu_alias.h
index dd7bfdcc0f..2a0c7ca7c3 100644
--- a/src/qemu/qemu_alias.h
+++ b/src/qemu/qemu_alias.h
@@ -92,6 +92,9 @@ char *qemuAliasForSecret(const char *parentalias,
 char *qemuAliasTLSx509ObjFromSrcAlias(const char *srcAlias)
     ATTRIBUTE_NONNULL(1);
 
+char *qemuAliasTLSPSKObjFromSrcAlias(const char *srcAlias)
+    ATTRIBUTE_NONNULL(1);
+
 char *qemuAliasChardevFromDevAlias(const char *devAlias)
     ATTRIBUTE_NONNULL(1);
 
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 9e7055f5da..296da1f195 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1702,12 +1702,13 @@ void
 qemuDomainDelTLSObjects(virDomainObj *vm,
                         virDomainAsyncJob asyncJob,
                         const char *secAlias,
-                        const char *tlsx509Alias)
+                        const char *tlsx509Alias,
+                        const char *tlsPSKAlias)
 {
     qemuDomainObjPrivate *priv = vm->privateData;
     virErrorPtr orig_err;
 
-    if (!tlsx509Alias && !secAlias)
+    if (!tlsx509Alias && !secAlias && !tlsPSKAlias)
         return;
 
     virErrorPreserveLast(&orig_err);
@@ -1721,6 +1722,9 @@ qemuDomainDelTLSObjects(virDomainObj *vm,
     if (secAlias)
         ignore_value(qemuMonitorDelObject(priv->mon, secAlias, false));
 
+    if (tlsPSKAlias)
+        ignore_value(qemuMonitorDelObject(priv->mon, tlsPSKAlias, false));
+
     qemuDomainObjExitMonitor(vm);
 
  cleanup:
@@ -1759,7 +1763,7 @@ qemuDomainAddTLSx509Objects(virDomainObj *vm,
     virErrorPreserveLast(&orig_err);
     qemuDomainObjExitMonitor(vm);
     virErrorRestore(&orig_err);
-    qemuDomainDelTLSObjects(vm, asyncJob, secAlias, NULL);
+    qemuDomainDelTLSObjects(vm, asyncJob, secAlias, NULL, NULL);
 
     return -1;
 }
@@ -1881,6 +1885,49 @@ qemuDomainDelChardevTLSObjects(virQEMUDriver *driver,
 }
 
 
+int
+qemuDomainAddTLSPSKObjects(virDomainObj *vm,
+                           virDomainAsyncJob asyncJob,
+                           virJSONValue **tlsPSKProps)
+{
+    qemuDomainObjPrivate *priv = vm->privateData;
+    virErrorPtr orig_err;
+
+    if (!tlsPSKProps)
+        return 0;
+
+    if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
+        return -1;
+
+    if (tlsPSKProps && *tlsPSKProps &&
+        qemuMonitorAddObject(priv->mon, tlsPSKProps, NULL) < 0)
+        goto error;
+
+    qemuDomainObjExitMonitor(vm);
+    return 0;
+
+ error:
+    virErrorPreserveLast(&orig_err);
+    qemuDomainObjExitMonitor(vm);
+    virErrorRestore(&orig_err);
+    return -1;
+}
+
+
+int
+qemuDomainGetTLSPSKObjects(const char *tlsPSKdir,
+                           bool tlsListen,
+                           const char *username,
+                           const char *alias,
+                           virJSONValue **tlsPSKProps)
+{
+    if (qemuBuildTLSPSKBackendProps(tlsPSKdir, tlsListen, username, alias, 
tlsPSKProps) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 static int
 qemuDomainAttachRedirdevDevice(virQEMUDriver *driver,
                                virDomainObj *vm,
@@ -1941,7 +1988,7 @@ qemuDomainAttachRedirdevDevice(virQEMUDriver *driver,
         ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
     qemuDomainObjExitMonitor(vm);
     virErrorRestore(&orig_err);
-    qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsx509Alias);
+    qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsx509Alias, 
NULL);
     goto audit;
 }
 
@@ -2240,7 +2287,7 @@ qemuDomainAttachChrDevice(virQEMUDriver *driver,
     qemuDomainObjExitMonitor(vm);
     virErrorRestore(&orig_err);
 
-    qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsx509Alias);
+    qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsx509Alias, 
NULL);
     goto audit;
 }
 
@@ -2345,7 +2392,7 @@ qemuDomainAttachRNGDevice(virQEMUDriver *driver,
     qemuDomainObjExitMonitor(vm);
     virErrorRestore(&orig_err);
 
-    qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsx509Alias);
+    qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsx509Alias, 
NULL);
     goto audit;
 }
 
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 2d9b10204c..835f57ded1 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -28,7 +28,8 @@ void
 qemuDomainDelTLSObjects(virDomainObj *vm,
                         virDomainAsyncJob asyncJob,
                         const char *secAlias,
-                        const char *tlsx509Alias);
+                        const char *tlsx509Alias,
+                        const char *tlsPSKAlias);
 
 int
 qemuDomainAddTLSx509Objects(virDomainObj *vm,
@@ -46,6 +47,18 @@ qemuDomainGetTLSx509Objects(qemuDomainSecretInfo *secinfo,
                             virJSONValue **tlsProps,
                             virJSONValue **secProps);
 
+int
+qemuDomainAddTLSPSKObjects(virDomainObj *vm,
+                           virDomainAsyncJob asyncJob,
+                           virJSONValue **tlsPSKProps);
+
+int
+qemuDomainGetTLSPSKObjects(const char *tlsPSKdir,
+                           bool tlsListen,
+                           const char *username,
+                           const char *alias,
+                           virJSONValue **tlsPSKProps);
+
 int
 qemuDomainAttachDiskGeneric(virDomainObj *vm,
                             virDomainDiskDef *disk,
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index c91ae89c9b..1c6ab6fc8a 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -1216,7 +1216,7 @@ qemuMigrationParamsEnableTLSx509(virQEMUDriver *driver,
      * This should prevent any issues just in case some cleanup wasn't
      * properly completed (both src and dst use the same alias) or
      * some other error path between now and perform . */
-    qemuDomainDelTLSObjects(vm, asyncJob, secAlias, *tlsx509Alias);
+    qemuDomainDelTLSObjects(vm, asyncJob, secAlias, *tlsx509Alias, NULL);
 
     if (qemuDomainAddTLSx509Objects(vm, asyncJob, &secProps, &tlsx509Props) < 
0)
         return -1;
@@ -1237,6 +1237,69 @@ qemuMigrationParamsEnableTLSx509(virQEMUDriver *driver,
 }
 
 
+/* qemuMigrationParamsEnableTLSPSK
+ * @driver: pointer to qemu driver
+ * @vm: domain object
+ * @tlsListen: server or client
+ * @asyncJob: Migration job to join
+ * @tlsPSKAlias: alias to be generated for TLS-PSK object
+ * @username: hostname of the migration destination
+ * @tls_psk_directory: directory containing the TLS-PSK key file
+ * @migParams: migration parameters to set
+ *
+ * Create the TLS PSK objects for the migration and set the migParams value.
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+qemuMigrationParamsEnableTLSPSK(virQEMUDriver *driver,
+                                virDomainObj *vm,
+                                bool tlsListen,
+                                int asyncJob,
+                                char **tlsPSKAlias,
+                                const char *username,
+                                qemuMigrationParams *migParams)
+{
+    qemuDomainJobPrivate *jobPriv = vm->job->privateData;
+    g_autoptr(virJSONValue) tlsPSKProps = NULL;
+    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+
+    if (!cfg->migrateTLSPSKdir) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                    _("host migration TLS-PSK directory not configured"));
+        return -1;
+    }
+
+    if (!jobPriv->migParams->params[QEMU_MIGRATION_PARAM_TLS_CREDS].set) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                    _("TLS migration is not supported with this QEMU binary"));
+        return -1;
+    }
+
+    if (!(*tlsPSKAlias = 
qemuAliasTLSPSKObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE)))
+        return -1;
+
+    if (qemuDomainGetTLSPSKObjects(cfg->migrateTLSPSKdir, tlsListen,
+                                username, *tlsPSKAlias, &tlsPSKProps) < 0)
+        return -1;
+
+    /* Ensure the domain doesn't already have the TLS-PSK objects defined...
+    * This should prevent any issues just in case some cleanup wasn't
+    * properly completed (both src and dst use the same alias) or
+    * some other error path between now and perform . */
+    qemuDomainDelTLSObjects(vm, asyncJob, NULL, NULL, *tlsPSKAlias);
+
+    if (qemuDomainAddTLSPSKObjects(vm, asyncJob, &tlsPSKProps) < 0)
+        return -1;
+
+    if (qemuMigrationParamsSetString(migParams, QEMU_MIGRATION_PARAM_TLS_CREDS,
+                                    *tlsPSKAlias) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 /* qemuMigrationParamsDisableTLS
  * @vm: domain object
  * @migParams: Pointer to a migration parameters block
@@ -1281,8 +1344,8 @@ qemuMigrationParamsTLSHostnameIsSet(qemuMigrationParams 
*migParams)
  * @asyncJob: migration job to join
  * @apiFlags: API flags used to start the migration
  *
- * Deconstruct all the setup possibly done for TLS - delete the TLS and
- * security objects and free the secinfo
+ * Deconstruct all the setup possibly done for TLS - delete the TLS X.509, 
TLS-PSK
+ * and security objects and free the secinfo
  */
 static void
 qemuMigrationParamsResetTLS(virDomainObj *vm,
@@ -1292,6 +1355,7 @@ qemuMigrationParamsResetTLS(virDomainObj *vm,
 {
     g_autofree char *tlsx509Alias = NULL;
     g_autofree char *secAlias = NULL;
+    g_autofree char *tlsPSKAlias = NULL;
 
     /* There's nothing to do if QEMU does not support TLS migration or we were
      * not asked to enable it. */
@@ -1301,8 +1365,9 @@ qemuMigrationParamsResetTLS(virDomainObj *vm,
 
     tlsx509Alias = 
qemuAliasTLSx509ObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE);
     secAlias = qemuAliasForSecret(QEMU_MIGRATION_TLS_ALIAS_BASE, NULL, 0);
+    tlsPSKAlias = 
qemuAliasTLSPSKObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE);
 
-    qemuDomainDelTLSObjects(vm, asyncJob, secAlias, tlsx509Alias);
+    qemuDomainDelTLSObjects(vm, asyncJob, secAlias, tlsx509Alias, tlsPSKAlias);
     g_clear_pointer(&QEMU_DOMAIN_PRIVATE(vm)->migSecinfo, 
qemuDomainSecretInfoFree);
 }
 
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index b578cf5091..07f5812065 100644
--- a/src/qemu/qemu_migration_params.h
+++ b/src/qemu/qemu_migration_params.h
@@ -123,6 +123,15 @@ qemuMigrationParamsEnableTLSx509(virQEMUDriver *driver,
                                  const char *hostname,
                                  qemuMigrationParams *migParams);
 
+int
+qemuMigrationParamsEnableTLSPSK(virQEMUDriver *driver,
+                                virDomainObj *vm,
+                                bool tlsListen,
+                                int asyncJob,
+                                char **tlsPSKAlias,
+                                const char *username,
+                                qemuMigrationParams *migParams);
+
 int
 qemuMigrationParamsDisableTLS(virDomainObj *vm,
                               qemuMigrationParams *migParams);
-- 
2.39.3

Reply via email to