2009-08-19 19:50:10 +00:00
|
|
|
/*
|
2014-03-28 03:26:44 +00:00
|
|
|
* virstorageencryption.c: volume encryption information
|
2009-08-19 19:50:10 +00:00
|
|
|
*
|
2014-03-06 14:57:47 +00:00
|
|
|
* Copyright (C) 2009-2014 Red Hat, Inc.
|
2009-08-19 19:50:10 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2009-08-19 19:50:10 +00:00
|
|
|
*
|
|
|
|
* Red Hat Author: Miloslav Trmač <mitr@redhat.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2009-08-14 18:06:59 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2009-08-19 19:50:10 +00:00
|
|
|
#include "internal.h"
|
|
|
|
|
2012-12-04 12:04:07 +00:00
|
|
|
#include "virbuffer.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2014-03-28 03:26:44 +00:00
|
|
|
#include "virstorageencryption.h"
|
2012-12-13 18:13:21 +00:00
|
|
|
#include "virxml.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2012-12-13 18:01:25 +00:00
|
|
|
#include "viruuid.h"
|
2011-07-19 18:32:58 +00:00
|
|
|
#include "virfile.h"
|
2009-08-19 19:50:10 +00:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_STORAGE
|
|
|
|
|
2014-05-14 19:48:15 +00:00
|
|
|
VIR_ENUM_IMPL(virStorageEncryptionSecret,
|
2009-08-19 19:50:10 +00:00
|
|
|
VIR_STORAGE_ENCRYPTION_SECRET_TYPE_LAST, "passphrase")
|
|
|
|
|
|
|
|
VIR_ENUM_IMPL(virStorageEncryptionFormat,
|
|
|
|
VIR_STORAGE_ENCRYPTION_FORMAT_LAST,
|
|
|
|
"default", "qcow")
|
|
|
|
|
|
|
|
static void
|
|
|
|
virStorageEncryptionSecretFree(virStorageEncryptionSecretPtr secret)
|
|
|
|
{
|
|
|
|
if (!secret)
|
|
|
|
return;
|
|
|
|
VIR_FREE(secret);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
virStorageEncryptionFree(virStorageEncryptionPtr enc)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (!enc)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < enc->nsecrets; i++)
|
|
|
|
virStorageEncryptionSecretFree(enc->secrets[i]);
|
|
|
|
VIR_FREE(enc->secrets);
|
|
|
|
VIR_FREE(enc);
|
|
|
|
}
|
|
|
|
|
2014-06-12 13:26:18 +00:00
|
|
|
static virStorageEncryptionSecretPtr
|
|
|
|
virStorageEncryptionSecretCopy(const virStorageEncryptionSecret *src)
|
|
|
|
{
|
|
|
|
virStorageEncryptionSecretPtr ret;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(ret) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
memcpy(ret, src, sizeof(*src));
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
virStorageEncryptionPtr
|
|
|
|
virStorageEncryptionCopy(const virStorageEncryption *src)
|
|
|
|
{
|
|
|
|
virStorageEncryptionPtr ret;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(ret) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(ret->secrets, src->nsecrets) < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
ret->nsecrets = src->nsecrets;
|
|
|
|
ret->format = src->format;
|
|
|
|
|
|
|
|
for (i = 0; i < src->nsecrets; i++) {
|
|
|
|
if (!(ret->secrets[i] = virStorageEncryptionSecretCopy(src->secrets[i])))
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virStorageEncryptionFree(ret);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-08-19 19:50:10 +00:00
|
|
|
static virStorageEncryptionSecretPtr
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
|
2009-08-19 19:50:10 +00:00
|
|
|
xmlNodePtr node)
|
|
|
|
{
|
|
|
|
xmlNodePtr old_node;
|
|
|
|
virStorageEncryptionSecretPtr ret;
|
|
|
|
char *type_str;
|
|
|
|
int type;
|
Fix UUID handling in secrets/storage encryption APIs
Convert all the secret/storage encryption APIs / wire format to
handle UUIDs in raw format instead of non-canonical printable
format. Guarentees data format correctness.
* docs/schemas/storageencryption.rng: Make UUID mandatory for a secret
and validate fully
* docs/schemas/secret.rng: Fully validate UUID
* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add
virSecretLookupByUUID and virSecretGetUUID. Make
virSecretGetUUIDString follow normal API design pattern
* python/generator.py: Skip generation of virSecretGetUUID,
virSecretGetUUIDString and virSecretLookupByUUID
* python/libvir.c, python/libvirt-python-api.xml: Manual impl
of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID
* qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/
Fix get_nonnull_secret/make_nonnull_secret to use unsigned char
* qemud/remote_protocol.x: Fix remote_nonnull_secret to use a
remote_uuid instead of remote_nonnull_string for UUID field.
Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to
REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an
remote_uuid value
* qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h,
qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h,
qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate
* src/datatypes.h, src/datatypes.c: Store UUID in raw format instead
of printable. Change virGetSecret to use raw format UUID
* src/driver.h: Rename virDrvSecretLookupByUUIDString to
virDrvSecretLookupByUUID and use raw format UUID
* src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID
and re-implement virSecretLookupByUUIDString and
virSecretGetUUIDString in terms of those
* src/libvirt_public.syms: Add virSecretLookupByUUID and
virSecretGetUUID
* src/remote_internal.c: Rename remoteSecretLookupByUUIDString
to remoteSecretLookupByUUID. Fix typo in args for
remoteSecretDefineXML impl. Use raw UUID format for
get_nonnull_secret and make_nonnull_secret
* src/storage_encryption_conf.c, src/storage_encryption_conf.h:
Storage UUID in raw format, and require it to be present in
XML. Use UUID parser to validate.
* secret_conf.h, secret_conf.c: Generate a UUID if none is provided.
Storage UUID in raw format.
* src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets
in a filed with printable UUID, instead of base64 UUID.
* src/virsh.c: Adjust for changed public API contract of
virSecretGetUUIDString.
* src/storage_Backend.c: DOn't undefine secret we just generated
upon successful volume creation. Fix to handle raw UUIDs. Generate
a non-clashing UUID
* src/qemu_driver.c: Change to use lookupByUUID instead of
lookupByUUIDString
2009-09-10 16:44:12 +00:00
|
|
|
char *uuidstr = NULL;
|
2009-08-19 19:50:10 +00:00
|
|
|
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC(ret) < 0)
|
2009-08-19 19:50:10 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
old_node = ctxt->node;
|
|
|
|
ctxt->node = node;
|
|
|
|
|
2010-02-04 21:52:34 +00:00
|
|
|
type_str = virXPathString("string(./@type)", ctxt);
|
2009-08-19 19:50:10 +00:00
|
|
|
if (type_str == NULL) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
|
_("unknown volume encryption secret type"));
|
2009-08-19 19:50:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2014-05-14 19:48:15 +00:00
|
|
|
type = virStorageEncryptionSecretTypeFromString(type_str);
|
2009-08-19 19:50:10 +00:00
|
|
|
if (type < 0) {
|
2014-01-10 16:41:33 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
2012-07-18 10:50:44 +00:00
|
|
|
_("unknown volume encryption secret type %s"),
|
|
|
|
type_str);
|
2009-08-19 19:50:10 +00:00
|
|
|
VIR_FREE(type_str);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VIR_FREE(type_str);
|
|
|
|
ret->type = type;
|
|
|
|
|
2010-02-04 21:52:34 +00:00
|
|
|
uuidstr = virXPathString("string(./@uuid)", ctxt);
|
Fix UUID handling in secrets/storage encryption APIs
Convert all the secret/storage encryption APIs / wire format to
handle UUIDs in raw format instead of non-canonical printable
format. Guarentees data format correctness.
* docs/schemas/storageencryption.rng: Make UUID mandatory for a secret
and validate fully
* docs/schemas/secret.rng: Fully validate UUID
* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add
virSecretLookupByUUID and virSecretGetUUID. Make
virSecretGetUUIDString follow normal API design pattern
* python/generator.py: Skip generation of virSecretGetUUID,
virSecretGetUUIDString and virSecretLookupByUUID
* python/libvir.c, python/libvirt-python-api.xml: Manual impl
of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID
* qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/
Fix get_nonnull_secret/make_nonnull_secret to use unsigned char
* qemud/remote_protocol.x: Fix remote_nonnull_secret to use a
remote_uuid instead of remote_nonnull_string for UUID field.
Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to
REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an
remote_uuid value
* qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h,
qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h,
qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate
* src/datatypes.h, src/datatypes.c: Store UUID in raw format instead
of printable. Change virGetSecret to use raw format UUID
* src/driver.h: Rename virDrvSecretLookupByUUIDString to
virDrvSecretLookupByUUID and use raw format UUID
* src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID
and re-implement virSecretLookupByUUIDString and
virSecretGetUUIDString in terms of those
* src/libvirt_public.syms: Add virSecretLookupByUUID and
virSecretGetUUID
* src/remote_internal.c: Rename remoteSecretLookupByUUIDString
to remoteSecretLookupByUUID. Fix typo in args for
remoteSecretDefineXML impl. Use raw UUID format for
get_nonnull_secret and make_nonnull_secret
* src/storage_encryption_conf.c, src/storage_encryption_conf.h:
Storage UUID in raw format, and require it to be present in
XML. Use UUID parser to validate.
* secret_conf.h, secret_conf.c: Generate a UUID if none is provided.
Storage UUID in raw format.
* src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets
in a filed with printable UUID, instead of base64 UUID.
* src/virsh.c: Adjust for changed public API contract of
virSecretGetUUIDString.
* src/storage_Backend.c: DOn't undefine secret we just generated
upon successful volume creation. Fix to handle raw UUIDs. Generate
a non-clashing UUID
* src/qemu_driver.c: Change to use lookupByUUID instead of
lookupByUUIDString
2009-09-10 16:44:12 +00:00
|
|
|
if (uuidstr) {
|
|
|
|
if (virUUIDParse(uuidstr, ret->uuid) < 0) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
_("malformed volume encryption uuid '%s'"),
|
|
|
|
uuidstr);
|
Fix UUID handling in secrets/storage encryption APIs
Convert all the secret/storage encryption APIs / wire format to
handle UUIDs in raw format instead of non-canonical printable
format. Guarentees data format correctness.
* docs/schemas/storageencryption.rng: Make UUID mandatory for a secret
and validate fully
* docs/schemas/secret.rng: Fully validate UUID
* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add
virSecretLookupByUUID and virSecretGetUUID. Make
virSecretGetUUIDString follow normal API design pattern
* python/generator.py: Skip generation of virSecretGetUUID,
virSecretGetUUIDString and virSecretLookupByUUID
* python/libvir.c, python/libvirt-python-api.xml: Manual impl
of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID
* qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/
Fix get_nonnull_secret/make_nonnull_secret to use unsigned char
* qemud/remote_protocol.x: Fix remote_nonnull_secret to use a
remote_uuid instead of remote_nonnull_string for UUID field.
Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to
REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an
remote_uuid value
* qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h,
qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h,
qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate
* src/datatypes.h, src/datatypes.c: Store UUID in raw format instead
of printable. Change virGetSecret to use raw format UUID
* src/driver.h: Rename virDrvSecretLookupByUUIDString to
virDrvSecretLookupByUUID and use raw format UUID
* src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID
and re-implement virSecretLookupByUUIDString and
virSecretGetUUIDString in terms of those
* src/libvirt_public.syms: Add virSecretLookupByUUID and
virSecretGetUUID
* src/remote_internal.c: Rename remoteSecretLookupByUUIDString
to remoteSecretLookupByUUID. Fix typo in args for
remoteSecretDefineXML impl. Use raw UUID format for
get_nonnull_secret and make_nonnull_secret
* src/storage_encryption_conf.c, src/storage_encryption_conf.h:
Storage UUID in raw format, and require it to be present in
XML. Use UUID parser to validate.
* secret_conf.h, secret_conf.c: Generate a UUID if none is provided.
Storage UUID in raw format.
* src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets
in a filed with printable UUID, instead of base64 UUID.
* src/virsh.c: Adjust for changed public API contract of
virSecretGetUUIDString.
* src/storage_Backend.c: DOn't undefine secret we just generated
upon successful volume creation. Fix to handle raw UUIDs. Generate
a non-clashing UUID
* src/qemu_driver.c: Change to use lookupByUUID instead of
lookupByUUIDString
2009-09-10 16:44:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-10-28 18:22:45 +00:00
|
|
|
VIR_FREE(uuidstr);
|
Fix UUID handling in secrets/storage encryption APIs
Convert all the secret/storage encryption APIs / wire format to
handle UUIDs in raw format instead of non-canonical printable
format. Guarentees data format correctness.
* docs/schemas/storageencryption.rng: Make UUID mandatory for a secret
and validate fully
* docs/schemas/secret.rng: Fully validate UUID
* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add
virSecretLookupByUUID and virSecretGetUUID. Make
virSecretGetUUIDString follow normal API design pattern
* python/generator.py: Skip generation of virSecretGetUUID,
virSecretGetUUIDString and virSecretLookupByUUID
* python/libvir.c, python/libvirt-python-api.xml: Manual impl
of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID
* qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/
Fix get_nonnull_secret/make_nonnull_secret to use unsigned char
* qemud/remote_protocol.x: Fix remote_nonnull_secret to use a
remote_uuid instead of remote_nonnull_string for UUID field.
Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to
REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an
remote_uuid value
* qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h,
qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h,
qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate
* src/datatypes.h, src/datatypes.c: Store UUID in raw format instead
of printable. Change virGetSecret to use raw format UUID
* src/driver.h: Rename virDrvSecretLookupByUUIDString to
virDrvSecretLookupByUUID and use raw format UUID
* src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID
and re-implement virSecretLookupByUUIDString and
virSecretGetUUIDString in terms of those
* src/libvirt_public.syms: Add virSecretLookupByUUID and
virSecretGetUUID
* src/remote_internal.c: Rename remoteSecretLookupByUUIDString
to remoteSecretLookupByUUID. Fix typo in args for
remoteSecretDefineXML impl. Use raw UUID format for
get_nonnull_secret and make_nonnull_secret
* src/storage_encryption_conf.c, src/storage_encryption_conf.h:
Storage UUID in raw format, and require it to be present in
XML. Use UUID parser to validate.
* secret_conf.h, secret_conf.c: Generate a UUID if none is provided.
Storage UUID in raw format.
* src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets
in a filed with printable UUID, instead of base64 UUID.
* src/virsh.c: Adjust for changed public API contract of
virSecretGetUUIDString.
* src/storage_Backend.c: DOn't undefine secret we just generated
upon successful volume creation. Fix to handle raw UUIDs. Generate
a non-clashing UUID
* src/qemu_driver.c: Change to use lookupByUUID instead of
lookupByUUIDString
2009-09-10 16:44:12 +00:00
|
|
|
} else {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
|
_("missing volume encryption uuid"));
|
Fix UUID handling in secrets/storage encryption APIs
Convert all the secret/storage encryption APIs / wire format to
handle UUIDs in raw format instead of non-canonical printable
format. Guarentees data format correctness.
* docs/schemas/storageencryption.rng: Make UUID mandatory for a secret
and validate fully
* docs/schemas/secret.rng: Fully validate UUID
* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add
virSecretLookupByUUID and virSecretGetUUID. Make
virSecretGetUUIDString follow normal API design pattern
* python/generator.py: Skip generation of virSecretGetUUID,
virSecretGetUUIDString and virSecretLookupByUUID
* python/libvir.c, python/libvirt-python-api.xml: Manual impl
of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID
* qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/
Fix get_nonnull_secret/make_nonnull_secret to use unsigned char
* qemud/remote_protocol.x: Fix remote_nonnull_secret to use a
remote_uuid instead of remote_nonnull_string for UUID field.
Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to
REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an
remote_uuid value
* qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h,
qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h,
qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate
* src/datatypes.h, src/datatypes.c: Store UUID in raw format instead
of printable. Change virGetSecret to use raw format UUID
* src/driver.h: Rename virDrvSecretLookupByUUIDString to
virDrvSecretLookupByUUID and use raw format UUID
* src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID
and re-implement virSecretLookupByUUIDString and
virSecretGetUUIDString in terms of those
* src/libvirt_public.syms: Add virSecretLookupByUUID and
virSecretGetUUID
* src/remote_internal.c: Rename remoteSecretLookupByUUIDString
to remoteSecretLookupByUUID. Fix typo in args for
remoteSecretDefineXML impl. Use raw UUID format for
get_nonnull_secret and make_nonnull_secret
* src/storage_encryption_conf.c, src/storage_encryption_conf.h:
Storage UUID in raw format, and require it to be present in
XML. Use UUID parser to validate.
* secret_conf.h, secret_conf.c: Generate a UUID if none is provided.
Storage UUID in raw format.
* src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets
in a filed with printable UUID, instead of base64 UUID.
* src/virsh.c: Adjust for changed public API contract of
virSecretGetUUIDString.
* src/storage_Backend.c: DOn't undefine secret we just generated
upon successful volume creation. Fix to handle raw UUIDs. Generate
a non-clashing UUID
* src/qemu_driver.c: Change to use lookupByUUID instead of
lookupByUUIDString
2009-09-10 16:44:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-08-19 19:50:10 +00:00
|
|
|
ctxt->node = old_node;
|
|
|
|
return ret;
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2009-08-19 19:50:10 +00:00
|
|
|
virStorageEncryptionSecretFree(ret);
|
Fix UUID handling in secrets/storage encryption APIs
Convert all the secret/storage encryption APIs / wire format to
handle UUIDs in raw format instead of non-canonical printable
format. Guarentees data format correctness.
* docs/schemas/storageencryption.rng: Make UUID mandatory for a secret
and validate fully
* docs/schemas/secret.rng: Fully validate UUID
* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add
virSecretLookupByUUID and virSecretGetUUID. Make
virSecretGetUUIDString follow normal API design pattern
* python/generator.py: Skip generation of virSecretGetUUID,
virSecretGetUUIDString and virSecretLookupByUUID
* python/libvir.c, python/libvirt-python-api.xml: Manual impl
of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID
* qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/
Fix get_nonnull_secret/make_nonnull_secret to use unsigned char
* qemud/remote_protocol.x: Fix remote_nonnull_secret to use a
remote_uuid instead of remote_nonnull_string for UUID field.
Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to
REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an
remote_uuid value
* qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h,
qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h,
qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate
* src/datatypes.h, src/datatypes.c: Store UUID in raw format instead
of printable. Change virGetSecret to use raw format UUID
* src/driver.h: Rename virDrvSecretLookupByUUIDString to
virDrvSecretLookupByUUID and use raw format UUID
* src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID
and re-implement virSecretLookupByUUIDString and
virSecretGetUUIDString in terms of those
* src/libvirt_public.syms: Add virSecretLookupByUUID and
virSecretGetUUID
* src/remote_internal.c: Rename remoteSecretLookupByUUIDString
to remoteSecretLookupByUUID. Fix typo in args for
remoteSecretDefineXML impl. Use raw UUID format for
get_nonnull_secret and make_nonnull_secret
* src/storage_encryption_conf.c, src/storage_encryption_conf.h:
Storage UUID in raw format, and require it to be present in
XML. Use UUID parser to validate.
* secret_conf.h, secret_conf.c: Generate a UUID if none is provided.
Storage UUID in raw format.
* src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets
in a filed with printable UUID, instead of base64 UUID.
* src/virsh.c: Adjust for changed public API contract of
virSecretGetUUIDString.
* src/storage_Backend.c: DOn't undefine secret we just generated
upon successful volume creation. Fix to handle raw UUIDs. Generate
a non-clashing UUID
* src/qemu_driver.c: Change to use lookupByUUID instead of
lookupByUUIDString
2009-09-10 16:44:12 +00:00
|
|
|
VIR_FREE(uuidstr);
|
2009-08-19 19:50:10 +00:00
|
|
|
ctxt->node = old_node;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virStorageEncryptionPtr
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageEncryptionParseXML(xmlXPathContextPtr ctxt)
|
2009-08-19 19:50:10 +00:00
|
|
|
{
|
|
|
|
xmlNodePtr *nodes = NULL;
|
|
|
|
virStorageEncryptionPtr ret;
|
|
|
|
char *format_str;
|
Convert 'int i' to 'size_t i' in src/conf/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
int format, n;
|
|
|
|
size_t i;
|
2009-08-19 19:50:10 +00:00
|
|
|
|
2013-07-04 10:02:00 +00:00
|
|
|
if (VIR_ALLOC(ret) < 0)
|
2009-08-19 19:50:10 +00:00
|
|
|
return NULL;
|
|
|
|
|
2010-02-04 21:52:34 +00:00
|
|
|
format_str = virXPathString("string(./@format)", ctxt);
|
2009-08-19 19:50:10 +00:00
|
|
|
if (format_str == NULL) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
|
_("unknown volume encryption format"));
|
2009-08-19 19:50:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
format = virStorageEncryptionFormatTypeFromString(format_str);
|
|
|
|
if (format < 0) {
|
2014-01-10 16:41:33 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
2012-07-18 10:50:44 +00:00
|
|
|
_("unknown volume encryption format type %s"),
|
|
|
|
format_str);
|
2009-08-19 19:50:10 +00:00
|
|
|
VIR_FREE(format_str);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VIR_FREE(format_str);
|
|
|
|
ret->format = format;
|
|
|
|
|
2010-02-04 21:52:34 +00:00
|
|
|
n = virXPathNodeSet("./secret", ctxt, &nodes);
|
2014-11-13 14:28:18 +00:00
|
|
|
if (n < 0)
|
2009-08-19 19:50:10 +00:00
|
|
|
goto cleanup;
|
2013-07-04 10:02:00 +00:00
|
|
|
if (n != 0 && VIR_ALLOC_N(ret->secrets, n) < 0)
|
2009-08-19 19:50:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
ret->nsecrets = n;
|
|
|
|
for (i = 0; i < n; i++) {
|
2010-02-10 11:42:56 +00:00
|
|
|
ret->secrets[i] = virStorageEncryptionSecretParse(ctxt, nodes[i]);
|
2009-08-19 19:50:10 +00:00
|
|
|
if (ret->secrets[i] == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VIR_FREE(nodes);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2009-08-19 19:50:10 +00:00
|
|
|
VIR_FREE(nodes);
|
|
|
|
virStorageEncryptionFree(ret);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
virStorageEncryptionPtr
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageEncryptionParseNode(xmlDocPtr xml, xmlNodePtr root)
|
2009-08-19 19:50:10 +00:00
|
|
|
{
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
virStorageEncryptionPtr enc = NULL;
|
|
|
|
|
|
|
|
if (STRNEQ((const char *) root->name, "encryption")) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
"%s", _("unknown root element for volume "
|
|
|
|
"encryption information"));
|
2009-08-19 19:50:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctxt = xmlXPathNewContext(xml);
|
|
|
|
if (ctxt == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-08-19 19:50:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctxt->node = root;
|
2010-02-10 11:42:56 +00:00
|
|
|
enc = virStorageEncryptionParseXML(ctxt);
|
2009-08-19 19:50:10 +00:00
|
|
|
|
2014-03-25 06:48:31 +00:00
|
|
|
cleanup:
|
2009-08-19 19:50:10 +00:00
|
|
|
xmlXPathFreeContext(ctxt);
|
|
|
|
return enc;
|
|
|
|
}
|
2009-09-01 20:37:42 +00:00
|
|
|
|
2009-08-19 19:50:10 +00:00
|
|
|
|
|
|
|
static int
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageEncryptionSecretFormat(virBufferPtr buf,
|
2011-09-22 18:16:26 +00:00
|
|
|
virStorageEncryptionSecretPtr secret)
|
2009-08-19 19:50:10 +00:00
|
|
|
{
|
|
|
|
const char *type;
|
Fix UUID handling in secrets/storage encryption APIs
Convert all the secret/storage encryption APIs / wire format to
handle UUIDs in raw format instead of non-canonical printable
format. Guarentees data format correctness.
* docs/schemas/storageencryption.rng: Make UUID mandatory for a secret
and validate fully
* docs/schemas/secret.rng: Fully validate UUID
* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add
virSecretLookupByUUID and virSecretGetUUID. Make
virSecretGetUUIDString follow normal API design pattern
* python/generator.py: Skip generation of virSecretGetUUID,
virSecretGetUUIDString and virSecretLookupByUUID
* python/libvir.c, python/libvirt-python-api.xml: Manual impl
of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID
* qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/
Fix get_nonnull_secret/make_nonnull_secret to use unsigned char
* qemud/remote_protocol.x: Fix remote_nonnull_secret to use a
remote_uuid instead of remote_nonnull_string for UUID field.
Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to
REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an
remote_uuid value
* qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h,
qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h,
qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate
* src/datatypes.h, src/datatypes.c: Store UUID in raw format instead
of printable. Change virGetSecret to use raw format UUID
* src/driver.h: Rename virDrvSecretLookupByUUIDString to
virDrvSecretLookupByUUID and use raw format UUID
* src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID
and re-implement virSecretLookupByUUIDString and
virSecretGetUUIDString in terms of those
* src/libvirt_public.syms: Add virSecretLookupByUUID and
virSecretGetUUID
* src/remote_internal.c: Rename remoteSecretLookupByUUIDString
to remoteSecretLookupByUUID. Fix typo in args for
remoteSecretDefineXML impl. Use raw UUID format for
get_nonnull_secret and make_nonnull_secret
* src/storage_encryption_conf.c, src/storage_encryption_conf.h:
Storage UUID in raw format, and require it to be present in
XML. Use UUID parser to validate.
* secret_conf.h, secret_conf.c: Generate a UUID if none is provided.
Storage UUID in raw format.
* src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets
in a filed with printable UUID, instead of base64 UUID.
* src/virsh.c: Adjust for changed public API contract of
virSecretGetUUIDString.
* src/storage_Backend.c: DOn't undefine secret we just generated
upon successful volume creation. Fix to handle raw UUIDs. Generate
a non-clashing UUID
* src/qemu_driver.c: Change to use lookupByUUID instead of
lookupByUUIDString
2009-09-10 16:44:12 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
2009-08-19 19:50:10 +00:00
|
|
|
|
2014-05-14 19:48:15 +00:00
|
|
|
type = virStorageEncryptionSecretTypeToString(secret->type);
|
2009-08-19 19:50:10 +00:00
|
|
|
if (!type) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("unexpected volume encryption secret type"));
|
2009-08-19 19:50:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
Fix UUID handling in secrets/storage encryption APIs
Convert all the secret/storage encryption APIs / wire format to
handle UUIDs in raw format instead of non-canonical printable
format. Guarentees data format correctness.
* docs/schemas/storageencryption.rng: Make UUID mandatory for a secret
and validate fully
* docs/schemas/secret.rng: Fully validate UUID
* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add
virSecretLookupByUUID and virSecretGetUUID. Make
virSecretGetUUIDString follow normal API design pattern
* python/generator.py: Skip generation of virSecretGetUUID,
virSecretGetUUIDString and virSecretLookupByUUID
* python/libvir.c, python/libvirt-python-api.xml: Manual impl
of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID
* qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/
Fix get_nonnull_secret/make_nonnull_secret to use unsigned char
* qemud/remote_protocol.x: Fix remote_nonnull_secret to use a
remote_uuid instead of remote_nonnull_string for UUID field.
Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to
REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an
remote_uuid value
* qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h,
qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h,
qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate
* src/datatypes.h, src/datatypes.c: Store UUID in raw format instead
of printable. Change virGetSecret to use raw format UUID
* src/driver.h: Rename virDrvSecretLookupByUUIDString to
virDrvSecretLookupByUUID and use raw format UUID
* src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID
and re-implement virSecretLookupByUUIDString and
virSecretGetUUIDString in terms of those
* src/libvirt_public.syms: Add virSecretLookupByUUID and
virSecretGetUUID
* src/remote_internal.c: Rename remoteSecretLookupByUUIDString
to remoteSecretLookupByUUID. Fix typo in args for
remoteSecretDefineXML impl. Use raw UUID format for
get_nonnull_secret and make_nonnull_secret
* src/storage_encryption_conf.c, src/storage_encryption_conf.h:
Storage UUID in raw format, and require it to be present in
XML. Use UUID parser to validate.
* secret_conf.h, secret_conf.c: Generate a UUID if none is provided.
Storage UUID in raw format.
* src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets
in a filed with printable UUID, instead of base64 UUID.
* src/virsh.c: Adjust for changed public API contract of
virSecretGetUUIDString.
* src/storage_Backend.c: DOn't undefine secret we just generated
upon successful volume creation. Fix to handle raw UUIDs. Generate
a non-clashing UUID
* src/qemu_driver.c: Change to use lookupByUUID instead of
lookupByUUIDString
2009-09-10 16:44:12 +00:00
|
|
|
virUUIDFormat(secret->uuid, uuidstr);
|
2014-03-06 14:57:47 +00:00
|
|
|
virBufferAsprintf(buf, "<secret type='%s' uuid='%s'/>\n",
|
2011-09-22 18:16:26 +00:00
|
|
|
type, uuidstr);
|
2009-08-19 19:50:10 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageEncryptionFormat(virBufferPtr buf,
|
2011-09-22 18:16:26 +00:00
|
|
|
virStorageEncryptionPtr enc)
|
2009-08-19 19:50:10 +00:00
|
|
|
{
|
|
|
|
const char *format;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
format = virStorageEncryptionFormatTypeToString(enc->format);
|
|
|
|
if (!format) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("unexpected encryption format"));
|
2009-08-19 19:50:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2011-09-22 18:16:26 +00:00
|
|
|
virBufferAsprintf(buf, "<encryption format='%s'>\n", format);
|
2014-03-06 14:57:47 +00:00
|
|
|
virBufferAdjustIndent(buf, 2);
|
2009-08-19 19:50:10 +00:00
|
|
|
|
|
|
|
for (i = 0; i < enc->nsecrets; i++) {
|
2011-09-22 18:16:26 +00:00
|
|
|
if (virStorageEncryptionSecretFormat(buf, enc->secrets[i]) < 0)
|
2009-08-19 19:50:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-03-06 14:57:47 +00:00
|
|
|
virBufferAdjustIndent(buf, -2);
|
2011-09-22 18:16:26 +00:00
|
|
|
virBufferAddLit(buf, "</encryption>\n");
|
2009-08-19 19:50:10 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2009-08-14 18:06:59 +00:00
|
|
|
|
|
|
|
int
|
2010-02-10 11:42:56 +00:00
|
|
|
virStorageGenerateQcowPassphrase(unsigned char *dest)
|
2009-08-14 18:06:59 +00:00
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
/* A qcow passphrase is up to 16 bytes, with any data following a NUL
|
|
|
|
ignored. Prohibit control and non-ASCII characters to avoid possible
|
|
|
|
unpleasant surprises with the qemu monitor input mechanism. */
|
|
|
|
fd = open("/dev/urandom", O_RDONLY);
|
|
|
|
if (fd < 0) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Cannot open /dev/urandom"));
|
2009-08-14 18:06:59 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
i = 0;
|
|
|
|
while (i < VIR_STORAGE_QCOW_PASSPHRASE_SIZE) {
|
|
|
|
ssize_t r;
|
|
|
|
|
|
|
|
while ((r = read(fd, dest + i, 1)) == -1 && errno == EINTR)
|
|
|
|
;
|
|
|
|
if (r <= 0) {
|
2012-07-18 10:50:44 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Cannot read from /dev/urandom"));
|
2010-10-19 14:23:51 +00:00
|
|
|
VIR_FORCE_CLOSE(fd);
|
2009-08-14 18:06:59 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (dest[i] >= 0x20 && dest[i] <= 0x7E)
|
|
|
|
i++; /* Got an acceptable character */
|
|
|
|
}
|
2010-10-19 14:23:51 +00:00
|
|
|
VIR_FORCE_CLOSE(fd);
|
2009-08-14 18:06:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|