[PATCH v2 0/6] Add TLS-PSK support for migration
QEMU provides the capability to encrypt the migration data stream using two transport layer security (TLS) authentication schemes: X.509 certificates and pre-shared keys (PSK). Currently, Libvirt only supports the X.509-based TLS authentication scheme. In TLS X.509 certificates, a set of live migrations utilize a fixed set of static certificates for encrypted migration. In this authentication scheme, users require to deploy a certificate authority and monitor the certificate expiration window. In case certificates are compromised all the future live migrations are vulnerable. To resolve this, this patch series introduce the support for pre-shared key-based authentication scheme. This mechanism relies on symmetric pre-shared keys (a secret key that is known to both sender and receiver prior to secure communication) for providing secure transfer of data. Libvirt solely manages the lifecycle of the ephemeral pre-shared keys, including, generation, persistent storage, and cleanup. Libvirt generates the key on the source machine, then transfers it to the destination machine using the migration cookie. To allow users to configure the size of the key, Libvirt provides the migrate_tls_psk_length configuration parameter in qemu.conf. To avoid introduction of an additional VIR_MIGRATE_* flag, we rely on existing the VIR_MIGRATE_TLS flag. If the VIR_MIGRATE_TLS flag is set but the ca-cert.pem file is missing on the source, then we fallback to using PSK-based authentication scheme during migration. v2: 1. Libvirt manages the lifecycle of pre-shared keys. 2. Transfer of keys to the destination via the migration cookie 3. Remove the VIR_MIGRATE_TLS_PSK flag instead rely on VIR_MIGRATE_TLS and availability of ca-cert.pem on source. 4. Drop VIR_MIGRATE_PARAM_TLS_PSK_DIRECTORY, Libvirt solely manages the pre-shared keys. Abhisek Panda (6): conf: Add a configuration param for TLS-PSK qemu: Manage a pre-shared key's lifecycle qemu: Add support to build the tls-creds-psk object qemu: rename tls-creds-x509 obj related functions qemu: Manage tls-creds-psk object lifecycle qemu: Set up the migrate TLS-PSK objects include/libvirt/libvirt-domain.h | 13 +- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf.in | 8 ++ src/qemu/qemu_alias.c | 19 ++- src/qemu/qemu_alias.h | 5 +- src/qemu/qemu_backup.c | 2 +- src/qemu/qemu_command.c | 28 +++- src/qemu/qemu_command.h | 7 + src/qemu/qemu_conf.c | 10 ++ src/qemu/qemu_conf.h | 1 + src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_hotplug.c | 124 +++++++++++----- src/qemu/qemu_hotplug.h | 42 ++++-- src/qemu/qemu_migration.c | 135 ++++++++++++++---- src/qemu/qemu_migration_cookie.c | 125 ++++++++++++++++ src/qemu/qemu_migration_cookie.h | 5 + src/qemu/qemu_migration_params.c | 109 ++++++++++---- src/qemu/qemu_migration_params.h | 22 ++- src/qemu/qemu_postparse.c | 2 +- src/qemu/test_libvirtd_qemu.aug.in | 1 + tests/qemumigparamsdata/tls-enabled.json | 2 +- tests/qemumigparamsdata/tls-enabled.reply | 2 +- tests/qemumigparamsdata/tls-enabled.xml | 2 +- tests/qemumigparamsdata/tls-hostname.json | 2 +- tests/qemumigparamsdata/tls-hostname.reply | 2 +- tests/qemumigparamsdata/tls-hostname.xml | 2 +- tests/qemumigrationcookiexmltest.c | 12 +- tests/qemumonitorjsontest.c | 4 +- tests/qemustatusxml2xmldata/upgrade-out.xml | 2 +- .../chardev-backends-json.x86_64-9.1.0.args | 8 +- .../chardev-backends-json.x86_64-latest.args | 8 +- .../chardev-backends.x86_64-9.1.0.args | 8 +- .../chardev-backends.x86_64-latest.args | 8 +- ...rk-tlsx509-nbd-hostname.x86_64-latest.args | 6 +- ...isk-network-tlsx509-nbd.x86_64-latest.args | 6 +- ...-tlsx509-chardev-verify.x86_64-latest.args | 4 +- ...ial-tcp-tlsx509-chardev.x86_64-latest.args | 4 +- ...-tlsx509-secret-chardev.x86_64-latest.args | 4 +- 38 files changed, 576 insertions(+), 171 deletions(-) -- 2.43.7
For encrypted migration of VMs, QEMU provides the TLS-PSK authentication apart from TLS certificates. This mechanism relies on pre-shared keys (a secret key that is known to both sender and receiver prior to secure communication) for providing secure transfer of data. Libvirt handles the lifecycle of pre-shared keys, managing their generation, persistent storage, and cleanup. Add the "migrate_tls_psk_length" configuration attribute to qemu.conf to allow users to define the size of the pre-shared key. Signed-off-by: Abhisek Panda <abhisek.panda1@nutanix.com> --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf.in | 8 ++++++++ src/qemu/qemu_conf.c | 10 ++++++++++ src/qemu/qemu_conf.h | 1 + src/qemu/test_libvirtd_qemu.aug.in | 1 + 5 files changed, 21 insertions(+) diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index 311992e441..d58f995282 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -68,6 +68,7 @@ module Libvirtd_qemu = | str_entry "migrate_tls_x509_secret_uuid" | str_entry "migrate_tls_priority" | bool_entry "migrate_tls_force" + | int_entry "migrate_tls_psk_length" let backup_entry = str_entry "backup_tls_x509_cert_dir" | bool_entry "backup_tls_x509_verify" diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in index 97b0141cf6..7f36bd1a68 100644 --- a/src/qemu/qemu.conf.in +++ b/src/qemu/qemu.conf.in @@ -437,6 +437,14 @@ #migrate_tls_force = 0 +# The TLS-PSK authentication relies on pre-shared keys for providing secure transfer of data. +# When TLS-PSK is enabled for the migration operation, Libvirt manages the lifecycle of the +# pre-shared key files. For the key generation process, users can specify the pre-shared +# key size in bytes. The default value is set to 32 bytes. +# +#migrate_tls_psk_length = 32 + + # In order to override the default TLS certificate location for backup NBD # server certificates, supply a valid path to the certificate directory. If the # provided path does not exist, libvirtd will fail to start. If the path is diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index e30b146634..d6abb82fed 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -77,6 +77,8 @@ VIR_LOG_INIT("qemu.qemu_conf"); #define QEMU_BACKUP_PORT_MIN 10809 #define QEMU_BACKUP_PORT_MAX 10872 +#define QEMU_MIGRATE_TLS_PSK_LENGTH 32 + VIR_ENUM_IMPL(virQEMUSchedCore, QEMU_SCHED_CORE_LAST, "none", @@ -616,6 +618,10 @@ virQEMUDriverConfigLoadSpecificTLSEntry(virQEMUDriverConfig *cfg, #undef GET_CONFIG_TLS_CERTINFO_COMMON #undef GET_CONFIG_TLS_CERTINFO_SERVER + + if (virConfGetValueUInt(conf, "migrate_tls_psk_length", &cfg->migrateTLSPSKLength) < 0) + return -1; + return 0; } @@ -1594,6 +1600,10 @@ virQEMUDriverConfigSetDefaults(virQEMUDriverConfig *cfg) #undef SET_TLS_VERIFY_DEFAULT + if (cfg->migrateTLSPSKLength == 0) { + cfg->migrateTLSPSKLength = QEMU_MIGRATE_TLS_PSK_LENGTH; + } + return 0; } diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 1d29f35c5d..c18aedf59c 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -170,6 +170,7 @@ struct _virQEMUDriverConfig { char *migrateTLSx509secretUUID; char *migrateTLSpriority; bool migrateTLSForce; + unsigned int migrateTLSPSKLength; char *backupTLSx509certdir; bool backupTLSx509verify; diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in index c4cf9cf634..7e337825fd 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -45,6 +45,7 @@ module Test_libvirtd_qemu = { "migrate_tls_x509_secret_uuid" = "00000000-0000-0000-0000-000000000000" } { "migrate_tls_priority" = "@SYSTEM" } { "migrate_tls_force" = "0" } +{ "migrate_tls_psk_length" = "32" } { "backup_tls_x509_cert_dir" = "/etc/pki/libvirt-backup" } { "backup_tls_x509_verify" = "1" } { "backup_tls_x509_secret_uuid" = "00000000-0000-0000-0000-000000000000" } -- 2.43.7
For enabling a TLS-PSK-enabled VM migration, we rely on the VIR_MIGRATE_TLS migration flag and existence of ca-cert.pem on the source. If the migration flag is set and ca-cert.pem doesn't exist on the source, then Libvirt fallbacks to PSK-based migration instead of X.509. Subsequently, it handles the generation, persistent storage, and cleanup of pre-shared keys on both source and destination. For a migration session, Libvirt generates a random key of the specified length, and then stores the content, "qemu:<random key>", at <runtime_state_dir>/<vm_uuid>/keys.psk on the source host. Subsequently, it sends the key to destination by embedding it within the migration cookie. The destination's Libvirt extracts the key from the migration cookie, and then persistently store it exactly the same way as the source. Upon migration completion or any failure, both source and destination Libvirt deletes the directory containing the session's keys.psk. Signed-off-by: Abhisek Panda <abhisek.panda1@nutanix.com> --- src/qemu/qemu_migration.c | 53 ++++++++++++ src/qemu/qemu_migration_cookie.c | 125 +++++++++++++++++++++++++++++ src/qemu/qemu_migration_cookie.h | 5 ++ tests/qemumigrationcookiexmltest.c | 12 +-- 4 files changed, 190 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 4a43ab83b0..72e13f854b 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1503,6 +1503,35 @@ qemuMigrationSrcIsAllowedHostdev(const virDomainDef *def) } +static bool +qemuMigrationCACertExists(virQEMUDriver *driver) +{ + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + g_autofree char *cert_path = g_strdup_printf("%s/ca-cert.pem", cfg->migrateTLSx509certdir); + if (!virFileExists(cert_path)) + return false; + + return true; +} + + +static void +qemuMigrationDeletePSKDir(virQEMUDriver *driver, virDomainObj *vm) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + g_autofree char *dir_path = NULL; + + virUUIDFormat(vm->def->uuid, uuidstr); + dir_path = g_strdup_printf("%s/%s", cfg->stateDir, uuidstr); + + if (virFileIsDir(dir_path) && + virFileDeleteTree(dir_path) < 0) + VIR_WARN("Failed to delete the directory %s containing the pre-shared keys for migration of domain %s", + dir_path, vm->def->name); +} + + static int qemuDomainGetMigrationBlockers(virDomainObj *vm, int asyncJob, @@ -2725,6 +2754,10 @@ qemuMigrationSrcBeginXML(virDomainObj *vm, if (!(flags & VIR_MIGRATE_OFFLINE)) cookieFlags |= QEMU_MIGRATION_COOKIE_CAPS; + if ((flags & VIR_MIGRATE_TLS) && + !qemuMigrationCACertExists(driver)) + cookieFlags |= QEMU_MIGRATION_COOKIE_TLS_PSK; + if (!(mig = qemuMigrationCookieNew(vm->def, priv->origname))) return NULL; @@ -4232,6 +4265,9 @@ qemuMigrationSrcConfirmPhase(virQEMUDriver *driver, privJob->stats.mig.downtime = privMigJob->stats.mig.downtime; } + if ((flags & VIR_MIGRATE_TLS) && !qemuMigrationCACertExists(driver)) + qemuMigrationDeletePSKDir(driver, vm); + if (flags & VIR_MIGRATE_OFFLINE) return 0; @@ -5275,6 +5311,9 @@ qemuMigrationSrcRun(virQEMUDriver *driver, error: virErrorPreserveLast(&orig_err); + if ((flags & VIR_MIGRATE_TLS) && !qemuMigrationCACertExists(driver)) + qemuMigrationDeletePSKDir(driver, vm); + if (qemuDomainObjIsActive(vm)) { int reason; virDomainState state = virDomainObjGetState(vm, &reason); @@ -7029,6 +7068,9 @@ qemuMigrationDstFinishActive(virQEMUDriver *driver, QEMU_MIGRATION_COOKIE_STATS) < 0) VIR_WARN("Unable to encode migration cookie"); + if (flags & VIR_MIGRATE_TLS) + qemuMigrationDeletePSKDir(driver, vm); + qemuMigrationDstComplete(driver, vm, inPostCopy, VIR_ASYNC_JOB_MIGRATION_IN, vm->job); @@ -7039,6 +7081,9 @@ qemuMigrationDstFinishActive(virQEMUDriver *driver, * overwrites it. */ virErrorPreserveLast(&orig_err); + if (flags & VIR_MIGRATE_TLS) + qemuMigrationDeletePSKDir(driver, vm); + if (qemuDomainObjIsActive(vm)) { if (doKill) { qemuProcessStop(vm, VIR_DOMAIN_SHUTOFF_FAILED, @@ -7197,6 +7242,14 @@ qemuMigrationProcessUnattended(virQEMUDriver *driver, else qemuMigrationSrcComplete(driver, vm, job); + /* + * Attempt to clean up the directory containing the pre-shared keys + * for the domain. Since, we cannot determine if the migration has + * enabled the VIR_MIGRATE_TLS flag with pre-shared keys, we clean up + * the directory unconditionally. + */ + qemuMigrationDeletePSKDir(driver, vm); + qemuMigrationJobFinish(vm); if (!virDomainObjIsActive(vm)) diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c index 7311a8294b..7734966983 100644 --- a/src/qemu/qemu_migration_cookie.c +++ b/src/qemu/qemu_migration_cookie.c @@ -20,9 +20,11 @@ #include <gnutls/gnutls.h> #include <gnutls/x509.h> +#include <inttypes.h> #include "locking/domain_lock.h" #include "virerror.h" +#include "virfile.h" #include "virlog.h" #include "virnetdevopenvswitch.h" #include "virstring.h" @@ -52,6 +54,7 @@ VIR_ENUM_IMPL(qemuMigrationCookieFlag, "allowReboot", "capabilities", "block-dirty-bitmaps", + "psk", ); @@ -149,6 +152,66 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuMigrationBlockDirtyBitmapsDisk, qemuMigrationBlockDirtyBitmapsDiskFree); +static int +qemuPersistTLSPSKHelper(int pskFD, + const char *pskPath, + const void *opaque) +{ + const char *key = opaque; + g_autofree char *psk_content = NULL; + + psk_content = g_strdup_printf("qemu:%s", key); + + if (safewrite(pskFD, psk_content, strlen(psk_content)) < 0) { + virReportSystemError(errno, + _("Unable to write the pre-shared key to file '%1$s'"), + pskPath); + return -1; + } + + return 0; +} + + +static int +qemuMigrationPersistPSK(qemuMigrationCookie *mig, virQEMUDriverConfig *cfg) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + g_autofree char *dir_path = NULL; + g_autofree char *key_path = NULL; + + virUUIDFormat(mig->uuid, uuidstr); + dir_path = g_strdup_printf("%s/%s", cfg->stateDir, uuidstr); + key_path = g_strdup_printf("%s/keys.psk", dir_path); + + if (virDirCreate(dir_path, 0700, cfg->user, cfg->group, + VIR_DIR_CREATE_ALLOW_EXIST) < 0) { + virReportSystemError(errno, + _("Could not create the directory %1$s for storing PSKs"), + dir_path); + goto error; + } + + if (mig->tlsPSK) { + if (virFileRewrite(key_path, S_IRUSR, cfg->user, + cfg->group, qemuPersistTLSPSKHelper, + mig->tlsPSK) < 0) + goto error; + } else { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("The pre-shared key for TLS-PSK migration is missing in the migration cookie")); + goto error; + } + + return 0; + + error: + if (virFileExists(dir_path)) + virFileDeleteTree(dir_path); + return -1; +} + + void qemuMigrationCookieFree(qemuMigrationCookie *mig) { @@ -165,6 +228,7 @@ qemuMigrationCookieFree(qemuMigrationCookie *mig) g_free(mig->name); g_free(mig->lockState); g_free(mig->lockDriver); + g_free(mig->tlsPSK); g_clear_pointer(&mig->jobData, virDomainJobDataFree); virCPUDefFree(mig->cpu); qemuMigrationCookieCapsFree(mig->caps); @@ -575,6 +639,48 @@ qemuMigrationCookieAddCaps(qemuMigrationCookie *mig, } +static int +qemuMigrationCookieAddTLSPSK(qemuMigrationCookie *mig, virQEMUDriver *driver) +{ + gnutls_datum_t psk_key = {NULL, 0}; + g_autofree char *key = NULL; + size_t key_len; + int ret; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + + ret = gnutls_key_generate(&psk_key, cfg->migrateTLSPSKLength); + if (ret < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Generation of a pre-shared key failed")); + return -1; + } + key_len = (psk_key.size*2) + 1; + key = g_new0(char, key_len); + + ret = gnutls_hex_encode(&psk_key, key, &key_len); + if (ret < 0) { + gnutls_free(psk_key.data); + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Hex encoding of a PSK key failed")); + return -1; + } + + mig->tlsPSK = g_steal_pointer(&key); + mig->flags |= QEMU_MIGRATION_COOKIE_TLS_PSK; + + ret = qemuMigrationPersistPSK(mig, cfg); + if (ret < 0) { + gnutls_free(psk_key.data); + g_free(mig->tlsPSK); + mig->tlsPSK = NULL; + return -1; + } + + gnutls_free(psk_key.data); + return 0; +} + + static void qemuMigrationCookieGraphicsXMLFormat(virBuffer *buf, qemuMigrationCookieGraphics *grap) @@ -890,6 +996,9 @@ qemuMigrationCookieXMLFormat(virQEMUDriver *driver, if (mig->flags & QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS) qemuMigrationCookieBlockDirtyBitmapsFormat(buf, mig->blockDirtyBitmaps); + if (mig->flags & QEMU_MIGRATION_COOKIE_TLS_PSK) + virBufferAsprintf(buf, "<migration-key>%s</migration-key>\n", mig->tlsPSK); + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</qemu-migration>\n"); return 0; @@ -1396,6 +1505,10 @@ qemuMigrationCookieXMLParse(qemuMigrationCookie *mig, qemuMigrationCookieBlockDirtyBitmapsParse(ctxt, mig) < 0) return -1; + if (flags & QEMU_MIGRATION_COOKIE_TLS_PSK) { + mig->tlsPSK = virXPathString("string(./migration-key[1])", ctxt); + } + return 0; } @@ -1471,6 +1584,10 @@ qemuMigrationCookieFormat(qemuMigrationCookie *mig, qemuMigrationCookieAddCaps(mig, dom, party) < 0) return -1; + if (flags & QEMU_MIGRATION_COOKIE_TLS_PSK && + qemuMigrationCookieAddTLSPSK(mig, driver) < 0) + return -1; + if (qemuMigrationCookieXMLFormat(driver, priv->qemuCaps, &buf, mig) < 0) return -1; @@ -1494,6 +1611,8 @@ qemuMigrationCookieParse(virQEMUDriver *driver, unsigned int flags) { g_autoptr(qemuMigrationCookie) mig = NULL; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + int ret; /* Parse & validate incoming cookie (if any) */ if (cookiein && cookieinlen && @@ -1537,6 +1656,12 @@ qemuMigrationCookieParse(virQEMUDriver *driver, } } + if ((flags & QEMU_MIGRATION_COOKIE_TLS_PSK) && mig->tlsPSK) { + ret = qemuMigrationPersistPSK(mig, cfg); + if (ret < 0) + return NULL; + } + if (vm && flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobData && vm->job->current) mig->jobData->operation = vm->job->current->operation; diff --git a/src/qemu/qemu_migration_cookie.h b/src/qemu/qemu_migration_cookie.h index 254372234d..fd3b4c5a56 100644 --- a/src/qemu/qemu_migration_cookie.h +++ b/src/qemu/qemu_migration_cookie.h @@ -35,6 +35,7 @@ typedef enum { QEMU_MIGRATION_COOKIE_FLAG_ALLOW_REBOOT, QEMU_MIGRATION_COOKIE_FLAG_CAPS, QEMU_MIGRATION_COOKIE_FLAG_BLOCK_DIRTY_BITMAPS, + QEMU_MIGRATION_COOKIE_FLAG_TLS_PSK, QEMU_MIGRATION_COOKIE_FLAG_LAST } qemuMigrationCookieFlags; @@ -53,6 +54,7 @@ typedef enum { QEMU_MIGRATION_COOKIE_CPU = (1 << QEMU_MIGRATION_COOKIE_FLAG_CPU), QEMU_MIGRATION_COOKIE_CAPS = (1 << QEMU_MIGRATION_COOKIE_FLAG_CAPS), QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS = (1 << QEMU_MIGRATION_COOKIE_FLAG_BLOCK_DIRTY_BITMAPS), + QEMU_MIGRATION_COOKIE_TLS_PSK = (1 << QEMU_MIGRATION_COOKIE_FLAG_TLS_PSK), } qemuMigrationCookieFeatures; typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics; @@ -171,6 +173,9 @@ struct _qemuMigrationCookie { /* If flags & QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS */ GSList *blockDirtyBitmaps; + + /* If flags & QEMU_MIGRATION_COOKIE_TLS_PSK */ + char *tlsPSK; }; diff --git a/tests/qemumigrationcookiexmltest.c b/tests/qemumigrationcookiexmltest.c index bc0f68b8c5..ee91c5d8b1 100644 --- a/tests/qemumigrationcookiexmltest.c +++ b/tests/qemumigrationcookiexmltest.c @@ -161,7 +161,7 @@ testQemuMigrationCookieParse(const void *opaque) } /* set all flags so that formatter attempts to format everything */ - data->cookie->flags = ~0; + data->cookie->flags = ~QEMU_MIGRATION_COOKIE_TLS_PSK; if (qemuMigrationCookieXMLFormat(&driver, priv->qemuCaps, @@ -225,15 +225,17 @@ testQemuMigrationCookieDom2XML(const char *namesuffix, * - lockstate: internals are NULL in tests, causes crash * - nbd: monitor not present * - dirty bitmaps: monitor not present + * - tls-psk: monitor not present */ unsigned int cookiePopulateFlagMask = QEMU_MIGRATION_COOKIE_LOCKSTATE | QEMU_MIGRATION_COOKIE_NBD | - QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS; + QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS | + QEMU_MIGRATION_COOKIE_TLS_PSK; data->cookiePopulateFlags = ~cookiePopulateFlagMask; } if (cookieParseFlags == 0) - data->cookieParseFlags = ~0; + data->cookieParseFlags = ~QEMU_MIGRATION_COOKIE_TLS_PSK; data->inStatus = g_strconcat(abs_srcdir, "/", domxml, NULL); @@ -279,7 +281,7 @@ testQemuMigrationCookieXML2XML(const char *name, int ret = 0; if (cookieParseFlags == 0) - data->cookieParseFlags = ~0; + data->cookieParseFlags = ~QEMU_MIGRATION_COOKIE_TLS_PSK; data->inStatus = g_strconcat(abs_srcdir, "/", statusxml, NULL); data->infile = g_strconcat(abs_srcdir, "/qemumigrationcookiexmldata/", @@ -381,7 +383,7 @@ testQemuMigrationCookieXML2XMLBitmaps(const char *name, int ret = 0; if (cookieParseFlags == 0) - data->cookieParseFlags = ~0; + data->cookieParseFlags = ~QEMU_MIGRATION_COOKIE_TLS_PSK; data->inStatus = g_strconcat(abs_srcdir, "/", statusxml, NULL); data->infile = g_strconcat(abs_srcdir, "/qemumigrationcookiexmldata/", -- 2.43.7
Build the tls-creds-psk object with the following params: id, dir, endpoint. Note: Libvirt generates a keys.psk file for each migration session that only contains the pre-shared key for the "qemu" user. Because QEMU defaults to using "qemu" as the username if the username attribute of the tls-creds-psk object is undefined. We intentionally do not set this attribute. Suggested-by: Tejus GK <tejus.gk@nutanix.com> Signed-off-by: Abhisek Panda <abhisek.panda1@nutanix.com> --- src/qemu/qemu_command.c | 26 ++++++++++++++++++++++++++ src/qemu/qemu_command.h | 7 +++++++ 2 files changed, 33 insertions(+) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index e726dc661c..6b72d74fc2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1293,6 +1293,32 @@ qemuBuildTLSx509CommandLine(virCommand *cmd, } +/* qemuBuildTLSPSKBackendProps: + * @tlsPSKPath: path to the TLS-PSK credentials file + * @isListen: boolean listen for client or server setting + * @alias: alias for the TLS-PSK object + * @propsret: json properties to return + * + * Create a backend string for the tls-creds-psk object. + * + * Returns 0 on success, -1 on failure with error set. + */ +int +qemuBuildTLSPSKBackendProps(const char *tlsPSKPath, + bool isListen, + const char *alias, + virJSONValue **propsret) +{ + if (qemuMonitorCreateObjectProps(propsret, "tls-creds-psk", alias, + "s:dir", tlsPSKPath, + "s:endpoint", (isListen ? "server": "client"), + NULL) < 0) + return -1; + + return 0; +} + + static int qemuBuildChardevCommand(virCommand *cmd, const virDomainChrSourceDef *dev, diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index e34172fbff..245c605b24 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -72,6 +72,13 @@ qemuBuildTLSx509BackendProps(const char *tlspath, const char *secalias, virJSONValue **propsret); +/* Generate the object properties for a tls-creds-psk */ +int +qemuBuildTLSPSKBackendProps(const char *tlsPSKPath, + bool isListen, + const char *alias, + virJSONValue **propsret); + /* Open a UNIX socket for chardev FD passing */ int qemuOpenChrChardevUNIXSocket(const virDomainChrSourceDef *dev); -- 2.43.7
Append 'x509' to the function identifiers managing the tls-creds-x509 objects. This defines the functions' scope and prevents naming conflicts with the introduction of functions related to tls-creds-psk in subsequent commits. Additionally, update the TLS x509 object alias from "obj%s_tls0" to "obj%s_tlsx509_0" along with relevant testcase changes. Suggested-by: Tejus GK <tejus.gk@nutanix.com> Signed-off-by: Abhisek Panda <abhisek.panda1@nutanix.com> --- src/qemu/qemu_alias.c | 8 +- src/qemu/qemu_alias.h | 2 +- src/qemu/qemu_backup.c | 2 +- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_hotplug.c | 76 +++++++++---------- src/qemu/qemu_hotplug.h | 26 +++---- src/qemu/qemu_migration.c | 24 +++--- src/qemu/qemu_migration_params.c | 44 +++++------ src/qemu/qemu_migration_params.h | 14 ++-- src/qemu/qemu_postparse.c | 2 +- tests/qemumigparamsdata/tls-enabled.json | 2 +- tests/qemumigparamsdata/tls-enabled.reply | 2 +- tests/qemumigparamsdata/tls-enabled.xml | 2 +- tests/qemumigparamsdata/tls-hostname.json | 2 +- tests/qemumigparamsdata/tls-hostname.reply | 2 +- tests/qemumigparamsdata/tls-hostname.xml | 2 +- tests/qemumonitorjsontest.c | 4 +- tests/qemustatusxml2xmldata/upgrade-out.xml | 2 +- .../chardev-backends-json.x86_64-9.1.0.args | 8 +- .../chardev-backends-json.x86_64-latest.args | 8 +- .../chardev-backends.x86_64-9.1.0.args | 8 +- .../chardev-backends.x86_64-latest.args | 8 +- ...rk-tlsx509-nbd-hostname.x86_64-latest.args | 6 +- ...isk-network-tlsx509-nbd.x86_64-latest.args | 6 +- ...-tlsx509-chardev-verify.x86_64-latest.args | 4 +- ...ial-tcp-tlsx509-chardev.x86_64-latest.args | 4 +- ...-tlsx509-secret-chardev.x86_64-latest.args | 4 +- 28 files changed, 138 insertions(+), 138 deletions(-) diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index 400ce73283..b41794a5fa 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -872,15 +872,15 @@ qemuAliasForSecret(const char *parentalias, return g_strdup_printf("%s-secret%zu", parentalias, secret_idx); } -/* qemuAliasTLSObjFromSrcAlias +/* qemuAliasTLSx509ObjFromSrcAlias * @srcAlias: Pointer to a source alias string * - * Generate and return a string to be used as the TLS object alias + * Generate and return a string to be used as the TLS X.509 object alias */ char * -qemuAliasTLSObjFromSrcAlias(const char *srcAlias) +qemuAliasTLSx509ObjFromSrcAlias(const char *srcAlias) { - return g_strdup_printf("obj%s_tls0", srcAlias); + return g_strdup_printf("obj%s_tlsx509_0", srcAlias); } diff --git a/src/qemu/qemu_alias.h b/src/qemu/qemu_alias.h index eae08020dc..dd7bfdcc0f 100644 --- a/src/qemu/qemu_alias.h +++ b/src/qemu/qemu_alias.h @@ -89,7 +89,7 @@ char *qemuAliasForSecret(const char *parentalias, const char *obj, size_t secret_idx); -char *qemuAliasTLSObjFromSrcAlias(const char *srcAlias) +char *qemuAliasTLSx509ObjFromSrcAlias(const char *srcAlias) ATTRIBUTE_NONNULL(1); char *qemuAliasChardevFromDevAlias(const char *devAlias) diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index a0544c83dc..9c496ee0c8 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -745,7 +745,7 @@ qemuBackupBeginPrepareTLS(virDomainObj *vm, virJSONValue **tlsSecretProps) { qemuDomainObjPrivate *priv = vm->privateData; - g_autofree char *tlsObjAlias = qemuAliasTLSObjFromSrcAlias(QEMU_BACKUP_TLS_ALIAS_BASE); + g_autofree char *tlsObjAlias = qemuAliasTLSx509ObjFromSrcAlias(QEMU_BACKUP_TLS_ALIAS_BASE); g_autoptr(qemuDomainSecretInfo) secinfo = NULL; const char *tlsKeySecretAlias = NULL; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6b72d74fc2..4107b2aeb0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1345,7 +1345,7 @@ qemuBuildChardevCommand(virCommand *cmd, tlsCertEncSecAlias = chrSourcePriv->secinfo->alias; } - if (!(objalias = qemuAliasTLSObjFromSrcAlias(charAlias))) + if (!(objalias = qemuAliasTLSx509ObjFromSrcAlias(charAlias))) return -1; if (qemuBuildTLSx509CommandLine(cmd, chrSourcePriv->tlsCertPath, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index a43a5c0e4f..1506bfd357 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -9046,7 +9046,7 @@ qemuProcessPrepareStorageSourceTLSNBD(virStorageSource *src, return -1; } - src->tlsAlias = qemuAliasTLSObjFromSrcAlias(parentAlias); + src->tlsAlias = qemuAliasTLSx509ObjFromSrcAlias(parentAlias); src->tlsCertdir = g_strdup(cfg->nbdTLSx509certdir); src->tlsPriority = g_strdup(cfg->nbdTLSpriority); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 5be567b510..d2add3f656 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1702,12 +1702,12 @@ void qemuDomainDelTLSObjects(virDomainObj *vm, virDomainAsyncJob asyncJob, const char *secAlias, - const char *tlsAlias) + const char *tlsx509Alias) { qemuDomainObjPrivate *priv = vm->privateData; virErrorPtr orig_err; - if (!tlsAlias && !secAlias) + if (!tlsx509Alias && !secAlias) return; virErrorPreserveLast(&orig_err); @@ -1715,8 +1715,8 @@ qemuDomainDelTLSObjects(virDomainObj *vm, if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) goto cleanup; - if (tlsAlias) - ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias, false)); + if (tlsx509Alias) + ignore_value(qemuMonitorDelObject(priv->mon, tlsx509Alias, false)); if (secAlias) ignore_value(qemuMonitorDelObject(priv->mon, secAlias, false)); @@ -1729,10 +1729,10 @@ qemuDomainDelTLSObjects(virDomainObj *vm, int -qemuDomainAddTLSObjects(virDomainObj *vm, - virDomainAsyncJob asyncJob, - virJSONValue **secProps, - virJSONValue **tlsProps) +qemuDomainAddTLSx509Objects(virDomainObj *vm, + virDomainAsyncJob asyncJob, + virJSONValue **secProps, + virJSONValue **tlsProps) { qemuDomainObjPrivate *priv = vm->privateData; virErrorPtr orig_err; @@ -1766,14 +1766,14 @@ qemuDomainAddTLSObjects(virDomainObj *vm, int -qemuDomainGetTLSObjects(qemuDomainSecretInfo *secinfo, - const char *tlsCertdir, - bool tlsListen, - bool tlsVerify, - const char *tlsPriority, - const char *alias, - virJSONValue **tlsProps, - virJSONValue **secProps) +qemuDomainGetTLSx509Objects(qemuDomainSecretInfo *secinfo, + const char *tlsCertdir, + bool tlsListen, + bool tlsVerify, + const char *tlsPriority, + const char *alias, + virJSONValue **tlsProps, + virJSONValue **secProps) { const char *secAlias = NULL; @@ -1798,7 +1798,7 @@ qemuDomainAddChardevTLSObjects(virQEMUDriver *driver, virDomainChrSourceDef *dev, char *devAlias, char *charAlias, - char **tlsAlias, + char **tlsx509Alias, const char **secAlias) { g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); @@ -1821,21 +1821,21 @@ qemuDomainAddChardevTLSObjects(virQEMUDriver *driver, if (secinfo) *secAlias = secinfo->alias; - if (!(*tlsAlias = qemuAliasTLSObjFromSrcAlias(charAlias))) + if (!(*tlsx509Alias = qemuAliasTLSx509ObjFromSrcAlias(charAlias))) return -1; - if (qemuDomainGetTLSObjects(secinfo, - cfg->chardevTLSx509certdir, - dev->data.tcp.listen, - cfg->chardevTLSx509verify, - cfg->chardevTLSpriority, - *tlsAlias, &tlsProps, &secProps) < 0) + if (qemuDomainGetTLSx509Objects(secinfo, + cfg->chardevTLSx509certdir, + dev->data.tcp.listen, + cfg->chardevTLSx509verify, + cfg->chardevTLSpriority, + *tlsx509Alias, &tlsProps, &secProps) < 0) return -1; dev->data.tcp.tlscreds = true; - if (qemuDomainAddTLSObjects(vm, VIR_ASYNC_JOB_NONE, - &secProps, &tlsProps) < 0) + if (qemuDomainAddTLSx509Objects(vm, VIR_ASYNC_JOB_NONE, + &secProps, &tlsProps) < 0) return -1; return 0; @@ -1850,7 +1850,7 @@ qemuDomainDelChardevTLSObjects(virQEMUDriver *driver, { g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); qemuDomainObjPrivate *priv = vm->privateData; - g_autofree char *tlsAlias = NULL; + g_autofree char *tlsx509Alias = NULL; g_autofree char *secAlias = NULL; if (dev->type != VIR_DOMAIN_CHR_TYPE_TCP || @@ -1858,7 +1858,7 @@ qemuDomainDelChardevTLSObjects(virQEMUDriver *driver, return 0; } - if (!(tlsAlias = qemuAliasTLSObjFromSrcAlias(inAlias))) + if (!(tlsx509Alias = qemuAliasTLSx509ObjFromSrcAlias(inAlias))) return -1; /* Best shot at this as the secinfo is destroyed after process launch @@ -1871,7 +1871,7 @@ qemuDomainDelChardevTLSObjects(virQEMUDriver *driver, qemuDomainObjEnterMonitor(vm); - ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias, false)); + ignore_value(qemuMonitorDelObject(priv->mon, tlsx509Alias, false)); if (secAlias) ignore_value(qemuMonitorDelObject(priv->mon, secAlias, false)); @@ -1892,7 +1892,7 @@ qemuDomainAttachRedirdevDevice(virQEMUDriver *driver, g_autofree char *charAlias = NULL; g_autoptr(virJSONValue) devprops = NULL; bool chardevAdded = false; - g_autofree char *tlsAlias = NULL; + g_autofree char *tlsx509Alias = NULL; const char *secAlias = NULL; virErrorPtr orig_err; @@ -1911,7 +1911,7 @@ qemuDomainAttachRedirdevDevice(virQEMUDriver *driver, if (qemuDomainAddChardevTLSObjects(driver, vm, redirdev->source, redirdev->info.alias, charAlias, - &tlsAlias, &secAlias) < 0) + &tlsx509Alias, &secAlias) < 0) goto audit; qemuDomainObjEnterMonitor(vm); @@ -1941,7 +1941,7 @@ qemuDomainAttachRedirdevDevice(virQEMUDriver *driver, ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias)); qemuDomainObjExitMonitor(vm); virErrorRestore(&orig_err); - qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsAlias); + qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsx509Alias); goto audit; } @@ -2127,7 +2127,7 @@ qemuDomainAttachChrDevice(virQEMUDriver *driver, bool teardowncgroup = false; bool teardowndevice = false; bool teardownlabel = false; - g_autofree char *tlsAlias = NULL; + g_autofree char *tlsx509Alias = NULL; const char *secAlias = NULL; bool need_release = false; bool guestfwd = false; @@ -2181,7 +2181,7 @@ qemuDomainAttachChrDevice(virQEMUDriver *driver, if (qemuDomainAddChardevTLSObjects(driver, vm, chr->source, chr->info.alias, charAlias, - &tlsAlias, &secAlias) < 0) + &tlsx509Alias, &secAlias) < 0) goto audit; qemuDomainObjEnterMonitor(vm); @@ -2240,7 +2240,7 @@ qemuDomainAttachChrDevice(virQEMUDriver *driver, qemuDomainObjExitMonitor(vm); virErrorRestore(&orig_err); - qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsAlias); + qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsx509Alias); goto audit; } @@ -2256,7 +2256,7 @@ qemuDomainAttachRNGDevice(virQEMUDriver *driver, g_autoptr(virJSONValue) devprops = NULL; g_autofree char *charAlias = NULL; g_autofree char *objAlias = NULL; - g_autofree char *tlsAlias = NULL; + g_autofree char *tlsx509Alias = NULL; const char *secAlias = NULL; bool releaseaddr = false; bool teardowncgroup = false; @@ -2294,7 +2294,7 @@ qemuDomainAttachRNGDevice(virQEMUDriver *driver, if (qemuDomainAddChardevTLSObjects(driver, vm, rng->source.chardev, rng->info.alias, charAlias, - &tlsAlias, &secAlias) < 0) + &tlsx509Alias, &secAlias) < 0) goto audit; } @@ -2345,7 +2345,7 @@ qemuDomainAttachRNGDevice(virQEMUDriver *driver, qemuDomainObjExitMonitor(vm); virErrorRestore(&orig_err); - qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsAlias); + qemuDomainDelTLSObjects(vm, VIR_ASYNC_JOB_NONE, secAlias, tlsx509Alias); goto audit; } diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 60ed0e174c..2d9b10204c 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -28,23 +28,23 @@ void qemuDomainDelTLSObjects(virDomainObj *vm, virDomainAsyncJob asyncJob, const char *secAlias, - const char *tlsAlias); + const char *tlsx509Alias); int -qemuDomainAddTLSObjects(virDomainObj *vm, - virDomainAsyncJob asyncJob, - virJSONValue **secProps, - virJSONValue **tlsProps); +qemuDomainAddTLSx509Objects(virDomainObj *vm, + virDomainAsyncJob asyncJob, + virJSONValue **secProps, + virJSONValue **tlsProps); int -qemuDomainGetTLSObjects(qemuDomainSecretInfo *secinfo, - const char *tlsCertdir, - bool tlsListen, - bool tlsVerify, - const char *tlsPriority, - const char *alias, - virJSONValue **tlsProps, - virJSONValue **secProps); +qemuDomainGetTLSx509Objects(qemuDomainSecretInfo *secinfo, + const char *tlsCertdir, + bool tlsListen, + bool tlsVerify, + const char *tlsPriority, + const char *alias, + virJSONValue **tlsProps, + virJSONValue **secProps); int qemuDomainAttachDiskGeneric(virDomainObj *vm, diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 72e13f854b..79b93fb6e9 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3359,7 +3359,7 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver, qemuDomainObjPrivate *priv = vm->privateData; qemuDomainJobPrivate *jobPriv = vm->job->privateData; qemuProcessIncomingDef *incoming = NULL; - g_autofree char *tlsAlias = NULL; + g_autofree char *tlsx509Alias = NULL; virObjectEvent *event = NULL; virErrorPtr origErr = NULL; int dataFD[2] = { -1, -1 }; @@ -3445,10 +3445,10 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver, /* Migrations using TLS need to add the "tls-creds-x509" object and * set the migration TLS parameters */ if (flags & VIR_MIGRATE_TLS) { - if (qemuMigrationParamsEnableTLS(driver, vm, true, - VIR_ASYNC_JOB_MIGRATION_IN, - &tlsAlias, NULL, - migParams) < 0) + if (qemuMigrationParamsEnableTLSx509(driver, vm, true, + VIR_ASYNC_JOB_MIGRATION_IN, + &tlsx509Alias, NULL, + migParams) < 0) goto error; } else { if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) @@ -3466,7 +3466,7 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver, goto error; } - nbdTLSAlias = tlsAlias; + nbdTLSAlias = tlsx509Alias; } if (qemuMigrationDstStartNBDServer(driver, vm, incoming->address, @@ -5012,7 +5012,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver, int ret = -1; qemuDomainObjPrivate *priv = vm->privateData; g_autoptr(qemuMigrationCookie) mig = NULL; - g_autofree char *tlsAlias = NULL; + g_autofree char *tlsx509Alias = NULL; qemuMigrationIOThread *iothread = NULL; VIR_AUTOCLOSE fd = -1; unsigned long restore_max_bandwidth = priv->migMaxBandwidth; @@ -5105,10 +5105,10 @@ qemuMigrationSrcRun(virQEMUDriver *driver, spec->destType == MIGRATION_DEST_FD) hostname = spec->dest.host.name; - if (qemuMigrationParamsEnableTLS(driver, vm, false, - VIR_ASYNC_JOB_MIGRATION_OUT, - &tlsAlias, hostname, - migParams) < 0) + if (qemuMigrationParamsEnableTLSx509(driver, vm, false, + VIR_ASYNC_JOB_MIGRATION_OUT, + &tlsx509Alias, hostname, + migParams) < 0) goto error; } else { if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) @@ -5163,7 +5163,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver, migrate_disks, migrate_disks_detect_zeroes, migrate_disks_target_zero, - dconn, tlsAlias, tlsHostname, + dconn, tlsx509Alias, tlsHostname, nbdURI, flags) < 0) { goto error; } diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index dd47516742..c91ae89c9b 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -1150,12 +1150,12 @@ qemuMigrationParamsSetString(qemuMigrationParams *migParams, } -/* qemuMigrationParamsEnableTLS +/* qemuMigrationParamsEnableTLSx509 * @driver: pointer to qemu driver * @vm: domain object * @tlsListen: server or client * @asyncJob: Migration job to join - * @tlsAlias: alias to be generated for TLS object + * @tlsx509Alias: alias to be generated for TLS X.509 object * @hostname: hostname of the migration destination * @migParams: migration parameters to set * @@ -1166,17 +1166,17 @@ qemuMigrationParamsSetString(qemuMigrationParams *migParams, * Returns 0 on success, -1 on failure */ int -qemuMigrationParamsEnableTLS(virQEMUDriver *driver, - virDomainObj *vm, - bool tlsListen, - int asyncJob, - char **tlsAlias, - const char *hostname, - qemuMigrationParams *migParams) +qemuMigrationParamsEnableTLSx509(virQEMUDriver *driver, + virDomainObj *vm, + bool tlsListen, + int asyncJob, + char **tlsx509Alias, + const char *hostname, + qemuMigrationParams *migParams) { qemuDomainObjPrivate *priv = vm->privateData; qemuDomainJobPrivate *jobPriv = vm->job->privateData; - g_autoptr(virJSONValue) tlsProps = NULL; + g_autoptr(virJSONValue) tlsx509Props = NULL; g_autoptr(virJSONValue) secProps = NULL; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); const char *secAlias = NULL; @@ -1202,28 +1202,28 @@ qemuMigrationParamsEnableTLS(virQEMUDriver *driver, secAlias = priv->migSecinfo->alias; } - if (!(*tlsAlias = qemuAliasTLSObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE))) + if (!(*tlsx509Alias = qemuAliasTLSx509ObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE))) return -1; - if (qemuDomainGetTLSObjects(priv->migSecinfo, - cfg->migrateTLSx509certdir, tlsListen, - cfg->migrateTLSx509verify, - cfg->migrateTLSpriority, - *tlsAlias, &tlsProps, &secProps) < 0) + if (qemuDomainGetTLSx509Objects(priv->migSecinfo, + cfg->migrateTLSx509certdir, tlsListen, + cfg->migrateTLSx509verify, + cfg->migrateTLSpriority, + *tlsx509Alias, &tlsx509Props, &secProps) < 0) return -1; /* Ensure the domain doesn't already have the TLS 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, secAlias, *tlsAlias); + qemuDomainDelTLSObjects(vm, asyncJob, secAlias, *tlsx509Alias); - if (qemuDomainAddTLSObjects(vm, asyncJob, &secProps, &tlsProps) < 0) + if (qemuDomainAddTLSx509Objects(vm, asyncJob, &secProps, &tlsx509Props) < 0) return -1; if (qemuMigrationParamsSetString(migParams, QEMU_MIGRATION_PARAM_TLS_CREDS, - *tlsAlias) < 0) + *tlsx509Alias) < 0) return -1; /* QEMU interprets an empty string for hostname as if it is not populated */ @@ -1290,7 +1290,7 @@ qemuMigrationParamsResetTLS(virDomainObj *vm, qemuMigrationParams *origParams, unsigned int apiFlags) { - g_autofree char *tlsAlias = NULL; + g_autofree char *tlsx509Alias = NULL; g_autofree char *secAlias = NULL; /* There's nothing to do if QEMU does not support TLS migration or we were @@ -1299,10 +1299,10 @@ qemuMigrationParamsResetTLS(virDomainObj *vm, !(apiFlags & VIR_MIGRATE_TLS)) return; - tlsAlias = qemuAliasTLSObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE); + tlsx509Alias = qemuAliasTLSx509ObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE); secAlias = qemuAliasForSecret(QEMU_MIGRATION_TLS_ALIAS_BASE, NULL, 0); - qemuDomainDelTLSObjects(vm, asyncJob, secAlias, tlsAlias); + qemuDomainDelTLSObjects(vm, asyncJob, secAlias, tlsx509Alias); 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 b7a829b85a..b578cf5091 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -115,13 +115,13 @@ qemuMigrationParamsApply(virDomainObj *vm, unsigned int apiFlags); int -qemuMigrationParamsEnableTLS(virQEMUDriver *driver, - virDomainObj *vm, - bool tlsListen, - int asyncJob, - char **tlsAlias, - const char *hostname, - qemuMigrationParams *migParams); +qemuMigrationParamsEnableTLSx509(virQEMUDriver *driver, + virDomainObj *vm, + bool tlsListen, + int asyncJob, + char **tlsx509Alias, + const char *hostname, + qemuMigrationParams *migParams); int qemuMigrationParamsDisableTLS(virDomainObj *vm, diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c index 9eda2f6b99..998d083a3d 100644 --- a/src/qemu/qemu_postparse.c +++ b/src/qemu/qemu_postparse.c @@ -278,7 +278,7 @@ qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *disk, if (parseFlags & VIR_DOMAIN_DEF_PARSE_STATUS && disk->src->haveTLS == VIR_TRISTATE_BOOL_YES && !disk->src->tlsAlias && - !(disk->src->tlsAlias = qemuAliasTLSObjFromSrcAlias(disk->info.alias))) + !(disk->src->tlsAlias = qemuAliasTLSx509ObjFromSrcAlias(disk->info.alias))) return -1; return 0; diff --git a/tests/qemumigparamsdata/tls-enabled.json b/tests/qemumigparamsdata/tls-enabled.json index 098d3ae148..b8d2f094a6 100644 --- a/tests/qemumigparamsdata/tls-enabled.json +++ b/tests/qemumigparamsdata/tls-enabled.json @@ -1,7 +1,7 @@ { "cpu-throttle-initial": 20, "cpu-throttle-increment": 10, - "tls-creds": "objlibvirt_migrate_tls0", + "tls-creds": "objlibvirt_migrate_tlsx509_0", "tls-hostname": "", "max-bandwidth": 33554432, "downtime-limit": 300 diff --git a/tests/qemumigparamsdata/tls-enabled.reply b/tests/qemumigparamsdata/tls-enabled.reply index e3ce8e7778..10fe78b4b9 100644 --- a/tests/qemumigparamsdata/tls-enabled.reply +++ b/tests/qemumigparamsdata/tls-enabled.reply @@ -4,7 +4,7 @@ "cpu-throttle-increment": 10, "tls-hostname": "", "cpu-throttle-initial": 20, - "tls-creds": "objlibvirt_migrate_tls0", + "tls-creds": "objlibvirt_migrate_tlsx509_0", "max-bandwidth": 33554432, "downtime-limit": 300 } diff --git a/tests/qemumigparamsdata/tls-enabled.xml b/tests/qemumigparamsdata/tls-enabled.xml index 554b6855d4..1f5da6530c 100644 --- a/tests/qemumigparamsdata/tls-enabled.xml +++ b/tests/qemumigparamsdata/tls-enabled.xml @@ -2,7 +2,7 @@ <migParams> <param name='cpu-throttle-initial' value='20'/> <param name='cpu-throttle-increment' value='10'/> - <param name='tls-creds' value='objlibvirt_migrate_tls0'/> + <param name='tls-creds' value='objlibvirt_migrate_tlsx509_0'/> <param name='tls-hostname' value=''/> <param name='max-bandwidth' value='33554432'/> <param name='downtime-limit' value='300'/> diff --git a/tests/qemumigparamsdata/tls-hostname.json b/tests/qemumigparamsdata/tls-hostname.json index 2943df769b..abd8f37e8a 100644 --- a/tests/qemumigparamsdata/tls-hostname.json +++ b/tests/qemumigparamsdata/tls-hostname.json @@ -1,7 +1,7 @@ { "cpu-throttle-initial": 20, "cpu-throttle-increment": 10, - "tls-creds": "objlibvirt_migrate_tls0", + "tls-creds": "objlibvirt_migrate_tlsx509_0", "tls-hostname": "f27-1.virt", "max-bandwidth": 33554432, "downtime-limit": 300 diff --git a/tests/qemumigparamsdata/tls-hostname.reply b/tests/qemumigparamsdata/tls-hostname.reply index f7e7a96bc5..551010e426 100644 --- a/tests/qemumigparamsdata/tls-hostname.reply +++ b/tests/qemumigparamsdata/tls-hostname.reply @@ -4,7 +4,7 @@ "cpu-throttle-increment": 10, "tls-hostname": "f27-1.virt", "cpu-throttle-initial": 20, - "tls-creds": "objlibvirt_migrate_tls0", + "tls-creds": "objlibvirt_migrate_tlsx509_0", "max-bandwidth": 33554432, "downtime-limit": 300 } diff --git a/tests/qemumigparamsdata/tls-hostname.xml b/tests/qemumigparamsdata/tls-hostname.xml index addb5e68a4..3dd0b6ae28 100644 --- a/tests/qemumigparamsdata/tls-hostname.xml +++ b/tests/qemumigparamsdata/tls-hostname.xml @@ -2,7 +2,7 @@ <migParams> <param name='cpu-throttle-initial' value='20'/> <param name='cpu-throttle-increment' value='10'/> - <param name='tls-creds' value='objlibvirt_migrate_tls0'/> + <param name='tls-creds' value='objlibvirt_migrate_tlsx509_0'/> <param name='tls-hostname' value='f27-1.virt'/> <param name='max-bandwidth' value='33554432'/> <param name='downtime-limit' value='300'/> diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index f59b97c1c3..a9cccfb1d1 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -665,7 +665,7 @@ qemuMonitorJSONTestAttachChardev(virDomainXMLOption *xmlopt, "'server':false}}}"); chr->data.tcp.tlscreds = true; - chrSourcePriv->tlsCredsAlias = qemuAliasTLSObjFromSrcAlias("alias"); + chrSourcePriv->tlsCredsAlias = qemuAliasTLSx509ObjFromSrcAlias("alias"); chr->logfile = g_strdup("/test/log"); CHECK("tcp", false, "{'id':'alias'," @@ -675,7 +675,7 @@ qemuMonitorJSONTestAttachChardev(virDomainXMLOption *xmlopt, "'port':'1234'}}," "'telnet':false," "'server':false," - "'tls-creds':'objalias_tls0'," + "'tls-creds':'objalias_tlsx509_0'," "'logfile':'/test/log'}}}"); } diff --git a/tests/qemustatusxml2xmldata/upgrade-out.xml b/tests/qemustatusxml2xmldata/upgrade-out.xml index c7bc7128df..8d82c83146 100644 --- a/tests/qemustatusxml2xmldata/upgrade-out.xml +++ b/tests/qemustatusxml2xmldata/upgrade-out.xml @@ -414,7 +414,7 @@ <host name='example.org' port='9999'/> <privateData> <objects> - <TLSx509 alias='objvirtio-disk6_tls0'/> + <TLSx509 alias='objvirtio-disk6_tlsx509_0'/> </objects> </privateData> </source> diff --git a/tests/qemuxmlconfdata/chardev-backends-json.x86_64-9.1.0.args b/tests/qemuxmlconfdata/chardev-backends-json.x86_64-9.1.0.args index fd1c94f8ed..1857c9c3c3 100644 --- a/tests/qemuxmlconfdata/chardev-backends-json.x86_64-9.1.0.args +++ b/tests/qemuxmlconfdata/chardev-backends-json.x86_64-9.1.0.args @@ -54,11 +54,11 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":10,"chardev":"charchannel9","id":"channel9","name":"chardev-tcp-listen-raw"}' \ -chardev '{"id":"charchannel10","backend":{"type":"socket","data":{"addr":{"type":"inet","data":{"host":"1.2.3.4","port":"5679"}},"telnet":true,"server":true,"wait":false}}}' \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":11,"chardev":"charchannel10","id":"channel10","name":"chardev-tcp-listen-telnet"}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharchannel11_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ --chardev '{"id":"charchannel11","backend":{"type":"socket","data":{"addr":{"type":"inet","data":{"host":"1.2.3.4","port":"5678"}},"telnet":false,"server":false,"reconnect":2,"tls-creds":"objcharchannel11_tls0"}}}' \ +-object '{"qom-type":"tls-creds-x509","id":"objcharchannel11_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ +-chardev '{"id":"charchannel11","backend":{"type":"socket","data":{"addr":{"type":"inet","data":{"host":"1.2.3.4","port":"5678"}},"telnet":false,"server":false,"reconnect":2,"tls-creds":"objcharchannel11_tlsx509_0"}}}' \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":12,"chardev":"charchannel11","id":"channel11","name":"chardev-tcp-connect-raw"}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharchannel12_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ --chardev '{"id":"charchannel12","backend":{"type":"socket","data":{"addr":{"type":"inet","data":{"host":"hostname.global.","port":"5679"}},"telnet":true,"server":false,"reconnect":2,"tls-creds":"objcharchannel12_tls0"}}}' \ +-object '{"qom-type":"tls-creds-x509","id":"objcharchannel12_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ +-chardev '{"id":"charchannel12","backend":{"type":"socket","data":{"addr":{"type":"inet","data":{"host":"hostname.global.","port":"5679"}},"telnet":true,"server":false,"reconnect":2,"tls-creds":"objcharchannel12_tlsx509_0"}}}' \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":13,"chardev":"charchannel12","id":"channel12","name":"chardev-tcp-connect-telnet"}' \ -chardev '{"id":"charchannel13","backend":{"type":"udp","data":{"remote":{"type":"inet","data":{"host":"127.0.0.1","port":"2222"}}}}}' \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":14,"chardev":"charchannel13","id":"channel13","name":"chardev-udp-nobind"}' \ diff --git a/tests/qemuxmlconfdata/chardev-backends-json.x86_64-latest.args b/tests/qemuxmlconfdata/chardev-backends-json.x86_64-latest.args index 7e5540ff09..d4fa40ed6c 100644 --- a/tests/qemuxmlconfdata/chardev-backends-json.x86_64-latest.args +++ b/tests/qemuxmlconfdata/chardev-backends-json.x86_64-latest.args @@ -54,11 +54,11 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":10,"chardev":"charchannel9","id":"channel9","name":"chardev-tcp-listen-raw"}' \ -chardev '{"id":"charchannel10","backend":{"type":"socket","data":{"addr":{"type":"inet","data":{"host":"1.2.3.4","port":"5679"}},"telnet":true,"server":true,"wait":false}}}' \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":11,"chardev":"charchannel10","id":"channel10","name":"chardev-tcp-listen-telnet"}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharchannel11_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ --chardev '{"id":"charchannel11","backend":{"type":"socket","data":{"addr":{"type":"inet","data":{"host":"1.2.3.4","port":"5678"}},"telnet":false,"server":false,"reconnect-ms":2000,"tls-creds":"objcharchannel11_tls0"}}}' \ +-object '{"qom-type":"tls-creds-x509","id":"objcharchannel11_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ +-chardev '{"id":"charchannel11","backend":{"type":"socket","data":{"addr":{"type":"inet","data":{"host":"1.2.3.4","port":"5678"}},"telnet":false,"server":false,"reconnect-ms":2000,"tls-creds":"objcharchannel11_tlsx509_0"}}}' \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":12,"chardev":"charchannel11","id":"channel11","name":"chardev-tcp-connect-raw"}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharchannel12_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ --chardev '{"id":"charchannel12","backend":{"type":"socket","data":{"addr":{"type":"inet","data":{"host":"hostname.global.","port":"5679"}},"telnet":true,"server":false,"reconnect-ms":2000,"tls-creds":"objcharchannel12_tls0"}}}' \ +-object '{"qom-type":"tls-creds-x509","id":"objcharchannel12_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ +-chardev '{"id":"charchannel12","backend":{"type":"socket","data":{"addr":{"type":"inet","data":{"host":"hostname.global.","port":"5679"}},"telnet":true,"server":false,"reconnect-ms":2000,"tls-creds":"objcharchannel12_tlsx509_0"}}}' \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":13,"chardev":"charchannel12","id":"channel12","name":"chardev-tcp-connect-telnet"}' \ -chardev '{"id":"charchannel13","backend":{"type":"udp","data":{"remote":{"type":"inet","data":{"host":"127.0.0.1","port":"2222"}}}}}' \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":14,"chardev":"charchannel13","id":"channel13","name":"chardev-udp-nobind"}' \ diff --git a/tests/qemuxmlconfdata/chardev-backends.x86_64-9.1.0.args b/tests/qemuxmlconfdata/chardev-backends.x86_64-9.1.0.args index 3a3128eb3e..78275b25ac 100644 --- a/tests/qemuxmlconfdata/chardev-backends.x86_64-9.1.0.args +++ b/tests/qemuxmlconfdata/chardev-backends.x86_64-9.1.0.args @@ -54,11 +54,11 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":10,"chardev":"charchannel9","id":"channel9","name":"chardev-tcp-listen-raw"}' \ -chardev socket,id=charchannel10,host=1.2.3.4,port=5679,telnet=on,server=on,wait=off \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":11,"chardev":"charchannel10","id":"channel10","name":"chardev-tcp-listen-telnet"}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharchannel11_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ --chardev socket,id=charchannel11,host=1.2.3.4,port=5678,reconnect=2,tls-creds=objcharchannel11_tls0 \ +-object '{"qom-type":"tls-creds-x509","id":"objcharchannel11_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ +-chardev socket,id=charchannel11,host=1.2.3.4,port=5678,reconnect=2,tls-creds=objcharchannel11_tlsx509_0 \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":12,"chardev":"charchannel11","id":"channel11","name":"chardev-tcp-connect-raw"}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharchannel12_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ --chardev socket,id=charchannel12,host=hostname.global.,port=5679,telnet=on,reconnect=2,tls-creds=objcharchannel12_tls0 \ +-object '{"qom-type":"tls-creds-x509","id":"objcharchannel12_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ +-chardev socket,id=charchannel12,host=hostname.global.,port=5679,telnet=on,reconnect=2,tls-creds=objcharchannel12_tlsx509_0 \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":13,"chardev":"charchannel12","id":"channel12","name":"chardev-tcp-connect-telnet"}' \ -chardev udp,id=charchannel13,host=127.0.0.1,port=2222,localaddr=,localport=0 \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":14,"chardev":"charchannel13","id":"channel13","name":"chardev-udp-nobind"}' \ diff --git a/tests/qemuxmlconfdata/chardev-backends.x86_64-latest.args b/tests/qemuxmlconfdata/chardev-backends.x86_64-latest.args index 68357c42f1..bc742db61c 100644 --- a/tests/qemuxmlconfdata/chardev-backends.x86_64-latest.args +++ b/tests/qemuxmlconfdata/chardev-backends.x86_64-latest.args @@ -54,11 +54,11 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":10,"chardev":"charchannel9","id":"channel9","name":"chardev-tcp-listen-raw"}' \ -chardev socket,id=charchannel10,host=1.2.3.4,port=5679,telnet=on,server=on,wait=off \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":11,"chardev":"charchannel10","id":"channel10","name":"chardev-tcp-listen-telnet"}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharchannel11_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ --chardev socket,id=charchannel11,host=1.2.3.4,port=5678,reconnect-ms=2000,tls-creds=objcharchannel11_tls0 \ +-object '{"qom-type":"tls-creds-x509","id":"objcharchannel11_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ +-chardev socket,id=charchannel11,host=1.2.3.4,port=5678,reconnect-ms=2000,tls-creds=objcharchannel11_tlsx509_0 \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":12,"chardev":"charchannel11","id":"channel11","name":"chardev-tcp-connect-raw"}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharchannel12_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ --chardev socket,id=charchannel12,host=hostname.global.,port=5679,telnet=on,reconnect-ms=2000,tls-creds=objcharchannel12_tls0 \ +-object '{"qom-type":"tls-creds-x509","id":"objcharchannel12_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ +-chardev socket,id=charchannel12,host=hostname.global.,port=5679,telnet=on,reconnect-ms=2000,tls-creds=objcharchannel12_tlsx509_0 \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":13,"chardev":"charchannel12","id":"channel12","name":"chardev-tcp-connect-telnet"}' \ -chardev udp,id=charchannel13,host=127.0.0.1,port=2222,localaddr=,localport=0 \ -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":14,"chardev":"charchannel13","id":"channel13","name":"chardev-udp-nobind"}' \ diff --git a/tests/qemuxmlconfdata/disk-network-tlsx509-nbd-hostname.x86_64-latest.args b/tests/qemuxmlconfdata/disk-network-tlsx509-nbd-hostname.x86_64-latest.args index ed3fb618f6..0aaf41dfea 100644 --- a/tests/qemuxmlconfdata/disk-network-tlsx509-nbd-hostname.x86_64-latest.args +++ b/tests/qemuxmlconfdata/disk-network-tlsx509-nbd-hostname.x86_64-latest.args @@ -27,9 +27,9 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -no-shutdown \ -boot strict=on \ -device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ --object '{"qom-type":"secret","id":"objlibvirt-1-storage_tls0-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ --object '{"qom-type":"tls-creds-x509","id":"objlibvirt-1-storage_tls0","dir":"/etc/pki/libvirt-nbd","endpoint":"client","verify-peer":true,"priority":"@SYSTEM:-VERS-TLS1.3","passwordid":"objlibvirt-1-storage_tls0-secret0"}' \ --blockdev '{"driver":"nbd","server":{"type":"inet","host":"example.com","port":"1234"},"tls-creds":"objlibvirt-1-storage_tls0","tls-hostname":"test-hostname","node-name":"libvirt-1-storage","read-only":false,"cache":{"direct":true,"no-flush":false}}' \ +-object '{"qom-type":"secret","id":"objlibvirt-1-storage_tlsx509_0-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ +-object '{"qom-type":"tls-creds-x509","id":"objlibvirt-1-storage_tlsx509_0","dir":"/etc/pki/libvirt-nbd","endpoint":"client","verify-peer":true,"priority":"@SYSTEM:-VERS-TLS1.3","passwordid":"objlibvirt-1-storage_tlsx509_0-secret0"}' \ +-blockdev '{"driver":"nbd","server":{"type":"inet","host":"example.com","port":"1234"},"tls-creds":"objlibvirt-1-storage_tlsx509_0","tls-hostname":"test-hostname","node-name":"libvirt-1-storage","read-only":false,"cache":{"direct":true,"no-flush":false}}' \ -device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x7","drive":"libvirt-1-storage","id":"virtio-disk3","bootindex":1,"write-cache":"on"}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ diff --git a/tests/qemuxmlconfdata/disk-network-tlsx509-nbd.x86_64-latest.args b/tests/qemuxmlconfdata/disk-network-tlsx509-nbd.x86_64-latest.args index 18e65ca27a..566d6ccb91 100644 --- a/tests/qemuxmlconfdata/disk-network-tlsx509-nbd.x86_64-latest.args +++ b/tests/qemuxmlconfdata/disk-network-tlsx509-nbd.x86_64-latest.args @@ -27,9 +27,9 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -no-shutdown \ -boot strict=on \ -device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ --object '{"qom-type":"secret","id":"objlibvirt-1-storage_tls0-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ --object '{"qom-type":"tls-creds-x509","id":"objlibvirt-1-storage_tls0","dir":"/etc/pki/libvirt-nbd","endpoint":"client","verify-peer":true,"passwordid":"objlibvirt-1-storage_tls0-secret0"}' \ --blockdev '{"driver":"nbd","server":{"type":"inet","host":"example.com","port":"1234"},"tls-creds":"objlibvirt-1-storage_tls0","node-name":"libvirt-1-storage","read-only":false,"cache":{"direct":true,"no-flush":false}}' \ +-object '{"qom-type":"secret","id":"objlibvirt-1-storage_tlsx509_0-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ +-object '{"qom-type":"tls-creds-x509","id":"objlibvirt-1-storage_tlsx509_0","dir":"/etc/pki/libvirt-nbd","endpoint":"client","verify-peer":true,"passwordid":"objlibvirt-1-storage_tlsx509_0-secret0"}' \ +-blockdev '{"driver":"nbd","server":{"type":"inet","host":"example.com","port":"1234"},"tls-creds":"objlibvirt-1-storage_tlsx509_0","node-name":"libvirt-1-storage","read-only":false,"cache":{"direct":true,"no-flush":false}}' \ -device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x7","drive":"libvirt-1-storage","id":"virtio-disk3","bootindex":1,"write-cache":"on"}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ diff --git a/tests/qemuxmlconfdata/serial-tcp-tlsx509-chardev-verify.x86_64-latest.args b/tests/qemuxmlconfdata/serial-tcp-tlsx509-chardev-verify.x86_64-latest.args index fa87b76d78..95685a66d9 100644 --- a/tests/qemuxmlconfdata/serial-tcp-tlsx509-chardev-verify.x86_64-latest.args +++ b/tests/qemuxmlconfdata/serial-tcp-tlsx509-chardev-verify.x86_64-latest.args @@ -31,8 +31,8 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-storage","id":"ide0-0-0","bootindex":1}' \ -chardev udp,id=charserial0,host=127.0.0.1,port=2222,localaddr=127.0.0.1,localport=1111 \ -device '{"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharserial1_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ --chardev socket,id=charserial1,host=127.0.0.1,port=5555,tls-creds=objcharserial1_tls0 \ +-object '{"qom-type":"tls-creds-x509","id":"objcharserial1_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ +-chardev socket,id=charserial1,host=127.0.0.1,port=5555,tls-creds=objcharserial1_tlsx509_0 \ -device '{"driver":"isa-serial","chardev":"charserial1","id":"serial1","index":1}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \ diff --git a/tests/qemuxmlconfdata/serial-tcp-tlsx509-chardev.x86_64-latest.args b/tests/qemuxmlconfdata/serial-tcp-tlsx509-chardev.x86_64-latest.args index fa87b76d78..95685a66d9 100644 --- a/tests/qemuxmlconfdata/serial-tcp-tlsx509-chardev.x86_64-latest.args +++ b/tests/qemuxmlconfdata/serial-tcp-tlsx509-chardev.x86_64-latest.args @@ -31,8 +31,8 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-storage","id":"ide0-0-0","bootindex":1}' \ -chardev udp,id=charserial0,host=127.0.0.1,port=2222,localaddr=127.0.0.1,localport=1111 \ -device '{"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharserial1_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ --chardev socket,id=charserial1,host=127.0.0.1,port=5555,tls-creds=objcharserial1_tls0 \ +-object '{"qom-type":"tls-creds-x509","id":"objcharserial1_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true}' \ +-chardev socket,id=charserial1,host=127.0.0.1,port=5555,tls-creds=objcharserial1_tlsx509_0 \ -device '{"driver":"isa-serial","chardev":"charserial1","id":"serial1","index":1}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \ diff --git a/tests/qemuxmlconfdata/serial-tcp-tlsx509-secret-chardev.x86_64-latest.args b/tests/qemuxmlconfdata/serial-tcp-tlsx509-secret-chardev.x86_64-latest.args index d127cc4ecf..4d61293d53 100644 --- a/tests/qemuxmlconfdata/serial-tcp-tlsx509-secret-chardev.x86_64-latest.args +++ b/tests/qemuxmlconfdata/serial-tcp-tlsx509-secret-chardev.x86_64-latest.args @@ -32,8 +32,8 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -chardev udp,id=charserial0,host=127.0.0.1,port=2222,localaddr=127.0.0.1,localport=1111 \ -device '{"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0}' \ -object '{"qom-type":"secret","id":"charserial1-secret0","data":"9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1","keyid":"masterKey0","iv":"AAECAwQFBgcICQoLDA0ODw==","format":"base64"}' \ --object '{"qom-type":"tls-creds-x509","id":"objcharserial1_tls0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true,"priority":"@SYSTEM:-VERS-TLS1.3","passwordid":"charserial1-secret0"}' \ --chardev socket,id=charserial1,host=127.0.0.1,port=5555,tls-creds=objcharserial1_tls0 \ +-object '{"qom-type":"tls-creds-x509","id":"objcharserial1_tlsx509_0","dir":"/etc/pki/libvirt-chardev","endpoint":"client","verify-peer":true,"priority":"@SYSTEM:-VERS-TLS1.3","passwordid":"charserial1-secret0"}' \ +-chardev socket,id=charserial1,host=127.0.0.1,port=5555,tls-creds=objcharserial1_tlsx509_0 \ -device '{"driver":"isa-serial","chardev":"charserial1","id":"serial1","index":1}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x3"}' \ -- 2.43.7
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 <tejus.gk@nutanix.com> Signed-off-by: Abhisek Panda <abhisek.panda1@nutanix.com> --- src/qemu/qemu_alias.c | 11 +++++ src/qemu/qemu_alias.h | 3 ++ src/qemu/qemu_hotplug.c | 58 ++++++++++++++++++++++++--- src/qemu/qemu_hotplug.h | 14 ++++++- src/qemu/qemu_migration_params.c | 69 ++++++++++++++++++++++++++++++-- src/qemu/qemu_migration_params.h | 8 ++++ 6 files changed, 152 insertions(+), 11 deletions(-) diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index b41794a5fa..a4894a681f 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_tlsx509_0", 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_tlspsk_0", 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 d2add3f656..75a2c75edf 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,48 @@ 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 *alias, + virJSONValue **tlsPSKProps) +{ + if (qemuBuildTLSPSKBackendProps(tlsPSKdir, tlsListen, alias, tlsPSKProps) < 0) + return -1; + + return 0; +} + + static int qemuDomainAttachRedirdevDevice(virQEMUDriver *driver, virDomainObj *vm, @@ -1941,7 +1987,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 +2286,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 +2391,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..984d3098a6 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,17 @@ qemuDomainGetTLSx509Objects(qemuDomainSecretInfo *secinfo, virJSONValue **tlsProps, virJSONValue **secProps); +int +qemuDomainAddTLSPSKObjects(virDomainObj *vm, + virDomainAsyncJob asyncJob, + virJSONValue **tlsPSKProps); + +int +qemuDomainGetTLSPSKObjects(const char *tlsPSKdir, + bool tlsListen, + 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..846d97b4d1 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,65 @@ 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 + * @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, + qemuMigrationParams *migParams) +{ + qemuDomainJobPrivate *jobPriv = vm->job->privateData; + g_autoptr(virJSONValue) tlsPSKProps = NULL; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + char uuidstr[VIR_UUID_STRING_BUFLEN]; + g_autofree char *dir_path = NULL; + + virUUIDFormat(vm->def->uuid, uuidstr); + dir_path = g_strdup_printf("%s/%s", cfg->stateDir, uuidstr); + + 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(dir_path, tlsListen, + *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. */ + 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 +1340,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 +1351,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 +1361,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..ad65c7933e 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -123,6 +123,14 @@ qemuMigrationParamsEnableTLSx509(virQEMUDriver *driver, const char *hostname, qemuMigrationParams *migParams); +int +qemuMigrationParamsEnableTLSPSK(virQEMUDriver *driver, + virDomainObj *vm, + bool tlsListen, + int asyncJob, + char **tlsPSKAlias, + qemuMigrationParams *migParams); + int qemuMigrationParamsDisableTLS(virDomainObj *vm, qemuMigrationParams *migParams); -- 2.43.7
On the source host enable TLS-PSK based secure migration, if and only if the VIR_MIGRATE_TLS flag is set and ca-cert.pem does not exist. This is because the TLS X.509-based migration utilize the ca-cert.pem file to verify the destination host. Subsequently, the source generates a pre-shared key and transmits it to the destination via a migration cookie. On the destination host, Libvirt unconditionally enables PSK-based migration if it receives the key via the cookie. Suggested-by: Tejus GK <tejus.gk@nutanix.com> Signed-off-by: Abhisek Panda <abhisek.panda1@nutanix.com> --- include/libvirt/libvirt-domain.h | 13 ++++-- src/qemu/qemu_migration.c | 74 ++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 5b67f8f897..e8b5d8451c 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1089,11 +1089,16 @@ 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 either the TLS X.509 or TLS pre-shared key (PSK) authentication + * mechanisms. If valid certificates and keys are present on the + * host, then TLS X.509 authentication scheme is used. However, if ca-cert.pem + * is missing on the source, then TLS PSK authentication scheme is used. + * In this case, the client must use a secure Libvirt to Libvirt communication + * channel because the pre-shared key is transmitted to the destination using the + * migration cookie. If the certificate or the key file is corrupted or not + * properly configured on either source or destination, the migration will fail. * - * Since: 3.2.0 + * Since: 12.4.0 */ VIR_MIGRATE_TLS = (1 << 16), diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 79b93fb6e9..bac5a953d1 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3360,6 +3360,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 }; @@ -3442,14 +3443,22 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver, /* Save original migration parameters */ qemuDomainSaveStatus(vm); - /* Migrations using TLS need to add the "tls-creds-x509" object and + /* Migrations using TLS need to add the "tls-creds-x509" object if the cert files are + * present on the host, else fallback to adding the "tls-creds-psk" object. Additionally, * 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; + if (!mig->tlsPSK) { + if (qemuMigrationParamsEnableTLSx509(driver, vm, true, + VIR_ASYNC_JOB_MIGRATION_IN, + &tlsx509Alias, NULL, + migParams) < 0) + goto error; + } else { + if (qemuMigrationParamsEnableTLSPSK(driver, vm, true, + VIR_ASYNC_JOB_MIGRATION_IN, + &tlsPSKAlias, migParams) < 0) + goto error; + } } else { if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) goto error; @@ -3556,6 +3565,13 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver, g_autofree char *xmlout = NULL; unsigned int cookieFlags = 0; bool taint_hook = false; + unsigned int parseCookieFlags = QEMU_MIGRATION_COOKIE_LOCKSTATE | + QEMU_MIGRATION_COOKIE_NBD | + QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG | + QEMU_MIGRATION_COOKIE_CPU_HOTPLUG | + QEMU_MIGRATION_COOKIE_CPU | + QEMU_MIGRATION_COOKIE_CAPS | + QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS; VIR_DEBUG("name=%s, origname=%s, protocol=%s, port=%hu, " "listenAddress=%s, nbdPort=%d, nbdURI=%s, flags=0x%x", @@ -3567,6 +3583,9 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver, QEMU_MIGRATION_COOKIE_CAPS; } + if (flags & VIR_MIGRATE_TLS) + parseCookieFlags |= QEMU_MIGRATION_COOKIE_TLS_PSK; + /* Let migration hook filter domain XML */ if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) { g_autofree char *xml = NULL; @@ -3613,14 +3632,7 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver, * domain list. Parsing/validation may fail and there's no * point in having the domain in the list at that point. */ if (!(mig = qemuMigrationCookieParse(driver, NULL, *def, origname, NULL, - cookiein, cookieinlen, - QEMU_MIGRATION_COOKIE_LOCKSTATE | - QEMU_MIGRATION_COOKIE_NBD | - QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG | - QEMU_MIGRATION_COOKIE_CPU_HOTPLUG | - QEMU_MIGRATION_COOKIE_CPU | - QEMU_MIGRATION_COOKIE_CAPS | - QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS))) + cookiein, cookieinlen, parseCookieFlags))) goto cleanup; if (!(vm = virDomainObjListAdd(driver->domains, def, @@ -5013,6 +5025,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; @@ -5097,19 +5110,26 @@ qemuMigrationSrcRun(virQEMUDriver *driver, 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; + if (qemuMigrationCACertExists(driver)) { + 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 (qemuMigrationParamsEnableTLSPSK(driver, vm, false, + VIR_ASYNC_JOB_MIGRATION_OUT, + &tlsPSKAlias, migParams) < 0) + goto error; + } } else { if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) goto error; -- 2.43.7
participants (1)
-
Abhisek Panda