mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
qemu: add multi-secret support in _qemuDomainStorageSourcePrivate
This commit changes the _qemuDomainStorageSourcePrivate struct to support multiple secrets (instead of a single one before this commit). This will useful for storage encryption requiring more than a single secret. Signed-off-by: Or Ozeri <oro@il.ibm.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
5c84e6fcdd
commit
1992ae40fa
@ -582,7 +582,7 @@ qemuBlockStorageSourceGetRBDProps(virStorageSource *src,
|
||||
|
||||
if (virJSONValueObjectAdd(&encrypt,
|
||||
"s:format", encformat,
|
||||
"s:key-secret", srcPriv->encinfo->alias,
|
||||
"s:key-secret", srcPriv->encinfo[0]->alias,
|
||||
NULL) < 0)
|
||||
return NULL;
|
||||
}
|
||||
@ -979,7 +979,8 @@ qemuBlockStorageSourceGetFormatLUKSProps(virStorageSource *src,
|
||||
{
|
||||
qemuDomainStorageSourcePrivate *srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
|
||||
|
||||
if (!srcPriv || !srcPriv->encinfo || !srcPriv->encinfo->alias) {
|
||||
/* validation ensures that the qemu encryption engine accepts only a single secret */
|
||||
if (!srcPriv || !srcPriv->encinfo || !srcPriv->encinfo[0]->alias) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("missing secret info for 'luks' driver"));
|
||||
return -1;
|
||||
@ -987,7 +988,7 @@ qemuBlockStorageSourceGetFormatLUKSProps(virStorageSource *src,
|
||||
|
||||
if (virJSONValueObjectAdd(&props,
|
||||
"s:driver", "luks",
|
||||
"s:key-secret", srcPriv->encinfo->alias,
|
||||
"s:key-secret", srcPriv->encinfo[0]->alias,
|
||||
NULL) < 0)
|
||||
return -1;
|
||||
|
||||
@ -1053,9 +1054,10 @@ qemuBlockStorageSourceGetCryptoProps(virStorageSource *src,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* validation ensures that the qemu encryption engine accepts only a single secret */
|
||||
return virJSONValueObjectAdd(encprops,
|
||||
"s:format", encformat,
|
||||
"s:key-secret", srcpriv->encinfo->alias,
|
||||
"s:key-secret", srcpriv->encinfo[0]->alias,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@ -1617,10 +1619,15 @@ qemuBlockStorageSourceDetachPrepare(virStorageSource *src)
|
||||
data->authsecretAlias = g_strdup(srcpriv->secinfo->alias);
|
||||
|
||||
if (srcpriv->encinfo) {
|
||||
data->encryptsecretCount = 1;
|
||||
data->encryptsecretProps = g_new0(virJSONValue *, 1);
|
||||
data->encryptsecretAlias = g_new0(char *, 1);
|
||||
data->encryptsecretAlias[0] = g_strdup(srcpriv->encinfo->alias);
|
||||
size_t i;
|
||||
|
||||
data->encryptsecretCount = srcpriv->enccount;
|
||||
data->encryptsecretProps = g_new0(virJSONValue *, srcpriv->enccount);
|
||||
data->encryptsecretAlias = g_new0(char *, srcpriv->enccount);
|
||||
|
||||
for (i = 0; i < srcpriv->enccount; ++i) {
|
||||
data->encryptsecretAlias[i] = g_strdup(srcpriv->encinfo[i]->alias);
|
||||
}
|
||||
}
|
||||
|
||||
if (srcpriv->httpcookie)
|
||||
@ -1986,7 +1993,7 @@ qemuBlockStorageSourceCreateGetEncryptionLUKS(virStorageSource *src,
|
||||
|
||||
if (srcpriv &&
|
||||
srcpriv->encinfo)
|
||||
keysecret = srcpriv->encinfo->alias;
|
||||
keysecret = srcpriv->encinfo[0]->alias;
|
||||
|
||||
if (virJSONValueObjectAdd(&props,
|
||||
"s:key-secret", keysecret,
|
||||
|
@ -1603,7 +1603,7 @@ qemuBuildDriveSourceStr(virDomainDiskDef *disk,
|
||||
{
|
||||
virStorageType actualType = virStorageSourceGetActualType(disk->src);
|
||||
qemuDomainStorageSourcePrivate *srcpriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(disk->src);
|
||||
qemuDomainSecretInfo *encinfo = NULL;
|
||||
qemuDomainSecretInfo **encinfo = NULL;
|
||||
g_autoptr(virJSONValue) srcprops = NULL;
|
||||
bool rawluks = false;
|
||||
|
||||
@ -1647,12 +1647,12 @@ qemuBuildDriveSourceStr(virDomainDiskDef *disk,
|
||||
|
||||
if (encinfo) {
|
||||
if (disk->src->format == VIR_STORAGE_FILE_RAW) {
|
||||
virBufferAsprintf(buf, "key-secret=%s,", encinfo->alias);
|
||||
virBufferAsprintf(buf, "key-secret=%s,", encinfo[0]->alias);
|
||||
rawluks = true;
|
||||
} else if (disk->src->format == VIR_STORAGE_FILE_QCOW2 &&
|
||||
disk->src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
|
||||
virBufferAddLit(buf, "encrypt.format=luks,");
|
||||
virBufferAsprintf(buf, "encrypt.key-secret=%s,", encinfo->alias);
|
||||
virBufferAsprintf(buf, "encrypt.key-secret=%s,", encinfo[0]->alias);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10777,12 +10777,16 @@ qemuBuildStorageSourceAttachPrepareCommon(virStorageSource *src,
|
||||
return -1;
|
||||
|
||||
if (srcpriv->encinfo) {
|
||||
data->encryptsecretCount = 1;
|
||||
data->encryptsecretProps = g_new0(virJSONValue *, 1);
|
||||
data->encryptsecretAlias = g_new0(char *, 1);
|
||||
size_t i;
|
||||
|
||||
if (qemuBuildSecretInfoProps(srcpriv->encinfo, &data->encryptsecretProps[0]) < 0)
|
||||
return -1;
|
||||
data->encryptsecretCount = srcpriv->enccount;
|
||||
data->encryptsecretProps = g_new0(virJSONValue *, srcpriv->enccount);
|
||||
data->encryptsecretAlias = g_new0(char *, srcpriv->enccount);
|
||||
|
||||
for (i = 0; i < srcpriv->enccount; ++i) {
|
||||
if (qemuBuildSecretInfoProps(srcpriv->encinfo[i], &data->encryptsecretProps[i]) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (srcpriv->httpcookie &&
|
||||
|
@ -872,7 +872,13 @@ qemuDomainStorageSourcePrivateDispose(void *obj)
|
||||
qemuDomainStorageSourcePrivate *priv = obj;
|
||||
|
||||
g_clear_pointer(&priv->secinfo, qemuDomainSecretInfoFree);
|
||||
g_clear_pointer(&priv->encinfo, qemuDomainSecretInfoFree);
|
||||
if (priv->encinfo) {
|
||||
size_t i;
|
||||
for (i = 0; i < priv->enccount; ++i) {
|
||||
g_clear_pointer(&priv->encinfo[i], qemuDomainSecretInfoFree);
|
||||
}
|
||||
VIR_FREE(priv->encinfo);
|
||||
}
|
||||
g_clear_pointer(&priv->httpcookie, qemuDomainSecretInfoFree);
|
||||
g_clear_pointer(&priv->tlsKeySecret, qemuDomainSecretInfoFree);
|
||||
g_clear_pointer(&priv->fdpass, qemuFDPassFree);
|
||||
@ -1401,7 +1407,13 @@ qemuDomainSecretDiskDestroy(virDomainDiskDef *disk)
|
||||
for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
|
||||
if ((srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(n))) {
|
||||
qemuDomainSecretInfoDestroy(srcPriv->secinfo);
|
||||
qemuDomainSecretInfoDestroy(srcPriv->encinfo);
|
||||
if (srcPriv->encinfo) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < srcPriv->enccount; ++i) {
|
||||
qemuDomainSecretInfoDestroy(srcPriv->encinfo[i]);
|
||||
}
|
||||
}
|
||||
qemuDomainSecretInfoDestroy(srcPriv->tlsKeySecret);
|
||||
}
|
||||
}
|
||||
@ -1470,12 +1482,19 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivate *priv,
|
||||
}
|
||||
|
||||
if (hasEnc) {
|
||||
if (!(srcPriv->encinfo = qemuDomainSecretInfoSetupFromSecret(priv, aliasformat,
|
||||
"encryption", 0,
|
||||
VIR_SECRET_USAGE_TYPE_VOLUME,
|
||||
NULL,
|
||||
&src->encryption->secrets[0]->seclookupdef)))
|
||||
return -1;
|
||||
size_t nsecrets = src->encryption->nsecrets;
|
||||
size_t i;
|
||||
|
||||
srcPriv->enccount = nsecrets;
|
||||
srcPriv->encinfo = g_new0(qemuDomainSecretInfo *, nsecrets);
|
||||
for (i = 0; i < nsecrets; ++i) {
|
||||
if (!(srcPriv->encinfo[i] = qemuDomainSecretInfoSetupFromSecret(priv, aliasformat,
|
||||
"encryption", i,
|
||||
VIR_SECRET_USAGE_TYPE_VOLUME,
|
||||
NULL,
|
||||
&src->encryption->secrets[i]->seclookupdef)))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (src->ncookies &&
|
||||
@ -1964,13 +1983,14 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
|
||||
virStorageSource *src)
|
||||
{
|
||||
qemuDomainStorageSourcePrivate *priv;
|
||||
g_autofree xmlNodePtr *encnodes = NULL;
|
||||
g_autofree char *authalias = NULL;
|
||||
g_autofree char *encalias = NULL;
|
||||
g_autofree char *httpcookiealias = NULL;
|
||||
g_autofree char *tlskeyalias = NULL;
|
||||
g_autofree char *thresholdEventWithIndex = NULL;
|
||||
bool fdsetPresent = false;
|
||||
unsigned int fdSetID;
|
||||
int enccount;
|
||||
|
||||
src->nodestorage = virXPathString("string(./nodenames/nodename[@type='storage']/@name)", ctxt);
|
||||
src->nodeformat = virXPathString("string(./nodenames/nodename[@type='format']/@name)", ctxt);
|
||||
@ -1983,13 +2003,14 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
|
||||
src->pr->mgralias = virXPathString("string(./reservations/@mgralias)", ctxt);
|
||||
|
||||
authalias = virXPathString("string(./objects/secret[@type='auth']/@alias)", ctxt);
|
||||
encalias = virXPathString("string(./objects/secret[@type='encryption']/@alias)", ctxt);
|
||||
if ((enccount = virXPathNodeSet("./objects/secret[@type='encryption']", ctxt, &encnodes)) < 0)
|
||||
return -1;
|
||||
httpcookiealias = virXPathString("string(./objects/secret[@type='httpcookie']/@alias)", ctxt);
|
||||
tlskeyalias = virXPathString("string(./objects/secret[@type='tlskey']/@alias)", ctxt);
|
||||
|
||||
fdsetPresent = virXPathUInt("string(./fdsets/fdset[@type='storage']/@id)", ctxt, &fdSetID) == 0;
|
||||
|
||||
if (authalias || encalias || httpcookiealias || tlskeyalias || fdsetPresent) {
|
||||
if (authalias || (enccount > 0) || httpcookiealias || tlskeyalias || fdsetPresent) {
|
||||
if (!src->privateData &&
|
||||
!(src->privateData = qemuDomainStorageSourcePrivateNew()))
|
||||
return -1;
|
||||
@ -1999,8 +2020,24 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
|
||||
if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->secinfo, &authalias) < 0)
|
||||
return -1;
|
||||
|
||||
if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo, &encalias) < 0)
|
||||
return -1;
|
||||
if (enccount > 0) {
|
||||
size_t i;
|
||||
|
||||
priv->enccount = enccount;
|
||||
priv->encinfo = g_new0(qemuDomainSecretInfo *, enccount);
|
||||
for (i = 0; i < enccount; ++i) {
|
||||
g_autofree char *encalias = NULL;
|
||||
|
||||
if (!(encalias = virXMLPropString(encnodes[i], "alias"))) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("missing alias on encryption secret #%lu"), i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo[i], &encalias) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->httpcookie, &httpcookiealias) < 0)
|
||||
return -1;
|
||||
@ -2061,10 +2098,13 @@ qemuStorageSourcePrivateDataFormat(virStorageSource *src,
|
||||
return -1;
|
||||
|
||||
if (srcPriv) {
|
||||
size_t i;
|
||||
unsigned int fdSetID;
|
||||
|
||||
qemuStorageSourcePrivateDataFormatSecinfo(&objectsChildBuf, srcPriv->secinfo, "auth");
|
||||
qemuStorageSourcePrivateDataFormatSecinfo(&objectsChildBuf, srcPriv->encinfo, "encryption");
|
||||
for (i = 0; i < srcPriv->enccount; ++i) {
|
||||
qemuStorageSourcePrivateDataFormatSecinfo(&objectsChildBuf, srcPriv->encinfo[i], "encryption");
|
||||
}
|
||||
qemuStorageSourcePrivateDataFormatSecinfo(&objectsChildBuf, srcPriv->httpcookie, "httpcookie");
|
||||
qemuStorageSourcePrivateDataFormatSecinfo(&objectsChildBuf, srcPriv->tlsKeySecret, "tlskey");
|
||||
|
||||
@ -5639,9 +5679,14 @@ qemuDomainDeviceDiskDefPostParseRestoreSecAlias(virDomainDiskDef *disk,
|
||||
}
|
||||
|
||||
if (restoreEncSecret) {
|
||||
if (!priv->encinfo) {
|
||||
priv->enccount = 1;
|
||||
priv->encinfo = g_new0(qemuDomainSecretInfo *, 1);
|
||||
}
|
||||
|
||||
encalias = g_strdup_printf("%s-luks-secret0", disk->info.alias);
|
||||
|
||||
if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo, &encalias) < 0)
|
||||
if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo[0], &encalias) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -296,7 +296,8 @@ struct _qemuDomainStorageSourcePrivate {
|
||||
qemuDomainSecretInfo *secinfo;
|
||||
|
||||
/* data required for decryption of encrypted storage source */
|
||||
qemuDomainSecretInfo *encinfo;
|
||||
size_t enccount;
|
||||
qemuDomainSecretInfo **encinfo;
|
||||
|
||||
/* secure passthrough of the http cookie */
|
||||
qemuDomainSecretInfo *httpcookie;
|
||||
|
@ -237,10 +237,11 @@ testQemuDiskXMLToJSONFakeSecrets(virStorageSource *src)
|
||||
}
|
||||
|
||||
if (src->encryption) {
|
||||
srcpriv->encinfo = g_new0(qemuDomainSecretInfo, 1);
|
||||
srcpriv->encinfo = g_new0(qemuDomainSecretInfo *, 1);
|
||||
srcpriv->encinfo[0] = g_new0(qemuDomainSecretInfo, 1);
|
||||
|
||||
srcpriv->encinfo->alias = g_strdup_printf("%s-encalias",
|
||||
NULLSTR(src->nodeformat));
|
||||
srcpriv->encinfo[0]->alias = g_strdup_printf("%s-encalias",
|
||||
NULLSTR(src->nodeformat));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -360,6 +360,20 @@
|
||||
</privateData>
|
||||
<diskSecretsPlacement auth='true'/>
|
||||
</disk>
|
||||
<disk type='network' device='disk'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source protocol='rbd' name='pool/image' tlsFromConfig='0'>
|
||||
<host name='example.org'/>
|
||||
<privateData>
|
||||
<objects>
|
||||
<secret type='encryption' alias='test-encryption-alias'/>
|
||||
<secret type='encryption' alias='test-encryption-alias2'/>
|
||||
</objects>
|
||||
</privateData>
|
||||
</source>
|
||||
<target dev='vdc' bus='virtio'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/var/lib/libvirt/images/systemrescuecd-x86-4.9.5.iso'/>
|
||||
|
Loading…
Reference in New Issue
Block a user