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
