diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 44fc271de9..93aaf2ad5a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -625,14 +625,22 @@ qemuBuildGeneralSecinfoURI(virURIPtr uri, if (!secinfo) return 0; - if (secinfo->s.plain.secret) { - if (virAsprintf(&uri->user, "%s:%s", - secinfo->s.plain.username, - secinfo->s.plain.secret) < 0) - return -1; - } else { - if (VIR_STRDUP(uri->user, secinfo->s.plain.username) < 0) - return -1; + switch ((qemuDomainSecretInfoType) secinfo->type) { + case VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN: + if (secinfo->s.plain.secret) { + if (virAsprintf(&uri->user, "%s:%s", + secinfo->s.plain.username, + secinfo->s.plain.secret) < 0) + return -1; + } else { + if (VIR_STRDUP(uri->user, secinfo->s.plain.username) < 0) + return -1; + } + break; + + case VIR_DOMAIN_SECRET_INFO_TYPE_IV: + case VIR_DOMAIN_SECRET_INFO_TYPE_LAST: + return -1; } return 0; @@ -659,11 +667,19 @@ qemuBuildRBDSecinfoURI(virBufferPtr buf, return 0; } - virBufferEscape(buf, '\\', ":", ":id=%s", - secinfo->s.plain.username); - virBufferEscape(buf, '\\', ":", - ":key=%s:auth_supported=cephx\\;none", - secinfo->s.plain.secret); + switch ((qemuDomainSecretInfoType) secinfo->type) { + case VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN: + virBufferEscape(buf, '\\', ":", ":id=%s", + secinfo->s.plain.username); + virBufferEscape(buf, '\\', ":", + ":key=%s:auth_supported=cephx\\;none", + secinfo->s.plain.secret); + break; + + case VIR_DOMAIN_SECRET_INFO_TYPE_IV: + case VIR_DOMAIN_SECRET_INFO_TYPE_LAST: + return -1; + } return 0; } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 6371988622..cae356cc89 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -736,13 +736,35 @@ qemuDomainSecretPlainFree(qemuDomainSecretPlain secret) } +static void +qemuDomainSecretIVFree(qemuDomainSecretIV secret) +{ + VIR_FREE(secret.username); + VIR_FREE(secret.alias); + VIR_FREE(secret.iv); + VIR_FREE(secret.ciphertext); +} + + static void qemuDomainSecretInfoFree(qemuDomainSecretInfoPtr *secinfo) { if (!*secinfo) return; - qemuDomainSecretPlainFree((*secinfo)->s.plain); + switch ((qemuDomainSecretInfoType) (*secinfo)->type) { + case VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN: + qemuDomainSecretPlainFree((*secinfo)->s.plain); + break; + + case VIR_DOMAIN_SECRET_INFO_TYPE_IV: + qemuDomainSecretIVFree((*secinfo)->s.iv); + break; + + case VIR_DOMAIN_SECRET_INFO_TYPE_LAST: + break; + } + VIR_FREE(*secinfo); } @@ -890,6 +912,7 @@ qemuDomainSecretDiskDestroy(virDomainDiskDefPtr disk) /* qemuDomainSecretDiskPrepare: * @conn: Pointer to connection + * @priv: pointer to domain private object * @disk: Pointer to a disk definition * * For the right disk, generate the qemuDomainSecretInfo structure. @@ -898,6 +921,7 @@ qemuDomainSecretDiskDestroy(virDomainDiskDefPtr disk) */ int qemuDomainSecretDiskPrepare(virConnectPtr conn, + qemuDomainObjPrivatePtr priv ATTRIBUTE_UNUSED, virDomainDiskDefPtr disk) { virStorageSourcePtr src = disk->src; @@ -949,6 +973,7 @@ qemuDomainSecretHostdevDestroy(virDomainHostdevDefPtr hostdev) /* qemuDomainSecretHostdevPrepare: * @conn: Pointer to connection + * @priv: pointer to domain private object * @hostdev: Pointer to a hostdev definition * * For the right host device, generate the qemuDomainSecretInfo structure. @@ -957,6 +982,7 @@ qemuDomainSecretHostdevDestroy(virDomainHostdevDefPtr hostdev) */ int qemuDomainSecretHostdevPrepare(virConnectPtr conn, + qemuDomainObjPrivatePtr priv ATTRIBUTE_UNUSED, virDomainHostdevDefPtr hostdev) { virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys; @@ -1029,15 +1055,17 @@ int qemuDomainSecretPrepare(virConnectPtr conn, virDomainObjPtr vm) { + qemuDomainObjPrivatePtr priv = vm->privateData; size_t i; for (i = 0; i < vm->def->ndisks; i++) { - if (qemuDomainSecretDiskPrepare(conn, vm->def->disks[i]) < 0) + if (qemuDomainSecretDiskPrepare(conn, priv, vm->def->disks[i]) < 0) return -1; } for (i = 0; i < vm->def->nhostdevs; i++) { - if (qemuDomainSecretHostdevPrepare(conn, vm->def->hostdevs[i]) < 0) + if (qemuDomainSecretHostdevPrepare(conn, priv, + vm->def->hostdevs[i]) < 0) return -1; } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 521ec3a2e0..5af802c02c 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -242,6 +242,7 @@ struct _qemuDomainObjPrivate { /* Type of domain secret */ typedef enum { VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN = 0, + VIR_DOMAIN_SECRET_INFO_TYPE_IV, VIR_DOMAIN_SECRET_INFO_TYPE_LAST } qemuDomainSecretInfoType; @@ -253,12 +254,24 @@ struct _qemuDomainSecretPlain { char *secret; }; +# define QEMU_DOMAIN_IV_KEY_LEN 16 /* 16 bytes for 128 bit random */ + /* initialization vector key */ +typedef struct _qemuDomainSecretIV qemuDomainSecretIV; +typedef struct _qemuDomainSecretIV *qemuDomainSecretIVPtr; +struct _qemuDomainSecretIV { + 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; + qemuDomainSecretIV iv; } s; }; @@ -634,15 +647,18 @@ void qemuDomainMasterKeyRemove(qemuDomainObjPrivatePtr priv); void qemuDomainSecretDiskDestroy(virDomainDiskDefPtr disk) ATTRIBUTE_NONNULL(1); -int qemuDomainSecretDiskPrepare(virConnectPtr conn, virDomainDiskDefPtr disk) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int qemuDomainSecretDiskPrepare(virConnectPtr conn, + qemuDomainObjPrivatePtr priv, + virDomainDiskDefPtr disk) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); void qemuDomainSecretHostdevDestroy(virDomainHostdevDefPtr disk) ATTRIBUTE_NONNULL(1); int qemuDomainSecretHostdevPrepare(virConnectPtr conn, + qemuDomainObjPrivatePtr priv, virDomainHostdevDefPtr hostdev) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); void qemuDomainSecretDestroy(virDomainObjPtr vm) ATTRIBUTE_NONNULL(1); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 03e5309507..73e2a67f94 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -370,7 +370,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) goto error; - if (qemuDomainSecretDiskPrepare(conn, disk) < 0) + if (qemuDomainSecretDiskPrepare(conn, priv, disk) < 0) goto error; if (!(drivestr = qemuBuildDriveStr(disk, false, priv->qemuCaps))) @@ -587,7 +587,7 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn, if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) goto error; - if (qemuDomainSecretDiskPrepare(conn, disk) < 0) + if (qemuDomainSecretDiskPrepare(conn, priv, disk) < 0) goto error; if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps))) @@ -1933,7 +1933,7 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn, if (qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1) < 0) goto cleanup; - if (qemuDomainSecretHostdevPrepare(conn, hostdev) < 0) + if (qemuDomainSecretHostdevPrepare(conn, priv, hostdev) < 0) goto cleanup; if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, priv->qemuCaps)))