Introduce API's to Prepare/Destroy a qemuDomainSecretInfoPtr to be used with a migrate or nbd TLS object Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/qemu/qemu_domain.c | 73 +++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.h | 88 +++++++++++++++++++++++++++++--------------------- 2 files changed, 124 insertions(+), 37 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index be44843..dd3cfd5 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1370,6 +1370,77 @@ qemuDomainSecretChardevPrepare(virConnectPtr conn, } +/* qemuDomainSecretMigrateDestroy: + * @migSecinfo: Pointer to the secinfo from the incoming def + * + * Clear and destroy memory associated with the secret + */ +void +qemuDomainSecretMigrateDestroy(qemuDomainSecretInfoPtr *migSecinfo) +{ + if (!*migSecinfo) + return; + + qemuDomainSecretInfoFree(migSecinfo); +} + + +/* qemuDomainSecretMigratePrepare + * @conn: Pointer to connection + * @priv: pointer to domain private object + * @srcAlias: Alias to use (either migrate or nbd) + * @secretUUID: UUID for the secret from the cfg (migrate or nbd) + * + * Create and prepare the qemuDomainSecretInfoPtr to be used for either + * a migration or nbd. Unlike other domain secret prepare functions, this + * is only expected to be called for a single object/instance. Theoretically + * the object could be reused, although that results in keeping a secret + * stored in memory for perhaps longer than expected or necessary. + * + * Returns 0 on success, -1 on failure + */ +int +qemuDomainSecretMigratePrepare(virConnectPtr conn, + qemuDomainObjPrivatePtr priv, + const char *srcAlias, + const char *secretUUID) +{ + virSecretLookupTypeDef seclookupdef = {0}; + qemuDomainSecretInfoPtr secinfo = NULL; + + if (virUUIDParse(secretUUID, seclookupdef.u.uuid) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("malformed %s TLS secret uuid in qemu.conf"), + srcAlias); + return -1; + } + seclookupdef.type = VIR_SECRET_LOOKUP_TYPE_UUID; + + if (VIR_ALLOC(secinfo) < 0) + return -1; + + if (qemuDomainSecretSetup(conn, priv, secinfo, srcAlias, + VIR_SECRET_USAGE_TYPE_TLS, NULL, + &seclookupdef, false) < 0) + goto error; + + if (secinfo->type == VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("TLS X.509 requires encrypted secrets " + "to be supported")); + goto error; + } + priv->migSecinfo = secinfo; + + return 0; + + error: + qemuDomainSecretInfoFree(&secinfo); + return -1; +} + + + /* qemuDomainSecretDestroy: * @vm: Domain object * @@ -1634,6 +1705,8 @@ qemuDomainObjPrivateFree(void *data) VIR_FREE(priv->libDir); VIR_FREE(priv->channelTargetDir); + + qemuDomainSecretMigrateDestroy(&priv->migSecinfo); qemuDomainMasterKeyFree(priv); VIR_FREE(priv); diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 524a672..f796306 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -175,6 +175,43 @@ VIR_ENUM_DECL(qemuDomainNamespace) bool qemuDomainNamespaceEnabled(virDomainObjPtr vm, qemuDomainNamespace ns); +/* Type of domain secret */ +typedef enum { + VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN = 0, + VIR_DOMAIN_SECRET_INFO_TYPE_AES, /* utilize GNUTLS_CIPHER_AES_256_CBC */ + + VIR_DOMAIN_SECRET_INFO_TYPE_LAST +} qemuDomainSecretInfoType; + +typedef struct _qemuDomainSecretPlain qemuDomainSecretPlain; +typedef struct _qemuDomainSecretPlain *qemuDomainSecretPlainPtr; +struct _qemuDomainSecretPlain { + char *username; + uint8_t *secret; + size_t secretlen; +}; + +# define QEMU_DOMAIN_AES_IV_LEN 16 /* 16 bytes for 128 bit random */ + /* initialization vector */ +typedef struct _qemuDomainSecretAES qemuDomainSecretAES; +typedef struct _qemuDomainSecretAES *qemuDomainSecretAESPtr; +struct _qemuDomainSecretAES { + char *username; + char *alias; /* generated alias for secret */ + char *iv; /* base64 encoded initialization vector */ + char *ciphertext; /* encoded/encrypted secret */ +}; + +typedef struct _qemuDomainSecretInfo qemuDomainSecretInfo; +typedef qemuDomainSecretInfo *qemuDomainSecretInfoPtr; +struct _qemuDomainSecretInfo { + qemuDomainSecretInfoType type; + union { + qemuDomainSecretPlain plain; + qemuDomainSecretAES aes; + } s; +}; + typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate; typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr; struct _qemuDomainObjPrivate { @@ -246,48 +283,15 @@ struct _qemuDomainObjPrivate { /* note whether memory device alias does not correspond to slot number */ bool memAliasOrderMismatch; + + /* for migration's using TLS with a secret (not to be saved in our */ + /* private XML). */ + qemuDomainSecretInfoPtr migSecinfo; }; # define QEMU_DOMAIN_PRIVATE(vm) \ ((qemuDomainObjPrivatePtr) (vm)->privateData) -/* Type of domain secret */ -typedef enum { - VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN = 0, - VIR_DOMAIN_SECRET_INFO_TYPE_AES, /* utilize GNUTLS_CIPHER_AES_256_CBC */ - - VIR_DOMAIN_SECRET_INFO_TYPE_LAST -} qemuDomainSecretInfoType; - -typedef struct _qemuDomainSecretPlain qemuDomainSecretPlain; -typedef struct _qemuDomainSecretPlain *qemuDomainSecretPlainPtr; -struct _qemuDomainSecretPlain { - char *username; - uint8_t *secret; - size_t secretlen; -}; - -# define QEMU_DOMAIN_AES_IV_LEN 16 /* 16 bytes for 128 bit random */ - /* initialization vector */ -typedef struct _qemuDomainSecretAES qemuDomainSecretAES; -typedef struct _qemuDomainSecretAES *qemuDomainSecretAESPtr; -struct _qemuDomainSecretAES { - char *username; - char *alias; /* generated alias for secret */ - char *iv; /* base64 encoded initialization vector */ - char *ciphertext; /* encoded/encrypted secret */ -}; - -typedef struct _qemuDomainSecretInfo qemuDomainSecretInfo; -typedef qemuDomainSecretInfo *qemuDomainSecretInfoPtr; -struct _qemuDomainSecretInfo { - qemuDomainSecretInfoType type; - union { - qemuDomainSecretPlain plain; - qemuDomainSecretAES aes; - } s; -}; - # define QEMU_DOMAIN_DISK_PRIVATE(disk) \ ((qemuDomainDiskPrivatePtr) (disk)->privateData) @@ -763,6 +767,16 @@ int qemuDomainSecretChardevPrepare(virConnectPtr conn, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5); +void qemuDomainSecretMigrateDestroy(qemuDomainSecretInfoPtr *migSecinfo) + ATTRIBUTE_NONNULL(1); + +int qemuDomainSecretMigratePrepare(virConnectPtr conn, + qemuDomainObjPrivatePtr priv, + const char *srcAlias, + const char *secretUUID) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_NONNULL(4); + void qemuDomainSecretDestroy(virDomainObjPtr vm) ATTRIBUTE_NONNULL(1); -- 2.9.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list