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
This commit is contained in:
Daniel P. Berrange 2009-09-10 17:44:12 +01:00
parent b22d935dbe
commit 47e7a258db
29 changed files with 468 additions and 231 deletions

View File

@ -25,7 +25,7 @@
<interleave> <interleave>
<optional> <optional>
<element name='uuid'> <element name='uuid'>
<text/> <ref name='UUID'/>
</element> </element>
</optional> </optional>
<optional> <optional>
@ -53,4 +53,16 @@
<text/> <text/>
</element> </element>
</define> </define>
<define name="UUID">
<choice>
<data type="string">
<param name="pattern">[a-fA-F0-9]{32}</param>
</data>
<data type="string">
<param name="pattern">[a-fA-F0-9]{8}\-([a-fA-F0-9]{4}\-){3}[a-fA-F0-9]{12}</param>
</data>
</choice>
</define>
</grammar> </grammar>

View File

@ -23,12 +23,21 @@
<value>passphrase</value> <value>passphrase</value>
</choice> </choice>
</attribute> </attribute>
<optional> <attribute name='uuid'>
<attribute name='uuid'> <ref name="UUID"/>
<text/> </attribute>
</attribute>
</optional>
</element> </element>
</define> </define>
<define name="UUID">
<choice>
<data type="string">
<param name="pattern">[a-fA-F0-9]{32}</param>
</data>
<data type="string">
<param name="pattern">[a-fA-F0-9]{8}\-([a-fA-F0-9]{4}\-){3}[a-fA-F0-9]{12}</param>
</data>
</choice>
</define>
</grammar> </grammar>

View File

@ -1467,12 +1467,17 @@ int virConnectNumOfSecrets (virConnectPtr conn);
int virConnectListSecrets (virConnectPtr conn, int virConnectListSecrets (virConnectPtr conn,
char **uuids, char **uuids,
int maxuuids); int maxuuids);
virSecretPtr virSecretLookupByUUID(virConnectPtr conn,
const unsigned char *uuid);
virSecretPtr virSecretLookupByUUIDString(virConnectPtr conn, virSecretPtr virSecretLookupByUUIDString(virConnectPtr conn,
const char *uuid); const char *uuid);
virSecretPtr virSecretDefineXML (virConnectPtr conn, virSecretPtr virSecretDefineXML (virConnectPtr conn,
const char *xml, const char *xml,
unsigned int flags); unsigned int flags);
char * virSecretGetUUIDString (virSecretPtr secret); int virSecretGetUUID (virSecretPtr secret,
unsigned char *buf);
int virSecretGetUUIDString (virSecretPtr secret,
char *buf);
char * virSecretGetXMLDesc (virSecretPtr secret, char * virSecretGetXMLDesc (virSecretPtr secret,
unsigned int flags); unsigned int flags);
int virSecretSetValue (virSecretPtr secret, int virSecretSetValue (virSecretPtr secret,

View File

@ -1467,12 +1467,17 @@ int virConnectNumOfSecrets (virConnectPtr conn);
int virConnectListSecrets (virConnectPtr conn, int virConnectListSecrets (virConnectPtr conn,
char **uuids, char **uuids,
int maxuuids); int maxuuids);
virSecretPtr virSecretLookupByUUID(virConnectPtr conn,
const unsigned char *uuid);
virSecretPtr virSecretLookupByUUIDString(virConnectPtr conn, virSecretPtr virSecretLookupByUUIDString(virConnectPtr conn,
const char *uuid); const char *uuid);
virSecretPtr virSecretDefineXML (virConnectPtr conn, virSecretPtr virSecretDefineXML (virConnectPtr conn,
const char *xml, const char *xml,
unsigned int flags); unsigned int flags);
char * virSecretGetUUIDString (virSecretPtr secret); int virSecretGetUUID (virSecretPtr secret,
unsigned char *buf);
int virSecretGetUUIDString (virSecretPtr secret,
char *buf);
char * virSecretGetXMLDesc (virSecretPtr secret, char * virSecretGetXMLDesc (virSecretPtr secret,
unsigned int flags); unsigned int flags);
int virSecretSetValue (virSecretPtr secret, int virSecretSetValue (virSecretPtr secret,

View File

@ -328,6 +328,9 @@ skip_impl = (
'virDomainPinVcpu', 'virDomainPinVcpu',
'virSecretGetValue', 'virSecretGetValue',
'virSecretSetValue', 'virSecretSetValue',
'virSecretGetUUID',
'virSecretGetUUIDString',
'virSecretLookupByUUID',
'virStoragePoolGetUUID', 'virStoragePoolGetUUID',
'virStoragePoolGetUUIDString', 'virStoragePoolGetUUIDString',
'virStoragePoolLookupByUUID', 'virStoragePoolLookupByUUID',

View File

@ -1562,6 +1562,82 @@ libvirt_virNodeDeviceListCaps(PyObject *self ATTRIBUTE_UNUSED,
return(py_retval); return(py_retval);
} }
static PyObject *
libvirt_virSecretGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_retval;
unsigned char uuid[VIR_UUID_BUFLEN];
virSecretPtr secret;
PyObject *pyobj_secret;
int c_retval;
if (!PyArg_ParseTuple(args, (char *)"O:virSecretGetUUID", &pyobj_secret))
return(NULL);
secret = (virSecretPtr) PyvirSecret_Get(pyobj_secret);
if (secret == NULL)
return VIR_PY_NONE;
LIBVIRT_BEGIN_ALLOW_THREADS;
c_retval = virSecretGetUUID(secret, &uuid[0]);
LIBVIRT_END_ALLOW_THREADS;
if (c_retval < 0)
return VIR_PY_NONE;
py_retval = PyString_FromStringAndSize((char *) &uuid[0], VIR_UUID_BUFLEN);
return(py_retval);
}
static PyObject *
libvirt_virSecretGetUUIDString(PyObject *self ATTRIBUTE_UNUSED,
PyObject *args) {
PyObject *py_retval;
char uuidstr[VIR_UUID_STRING_BUFLEN];
virSecretPtr dom;
PyObject *pyobj_dom;
int c_retval;
if (!PyArg_ParseTuple(args, (char *)"O:virSecretGetUUIDString",
&pyobj_dom))
return(NULL);
dom = (virSecretPtr) PyvirSecret_Get(pyobj_dom);
if (dom == NULL)
return VIR_PY_NONE;
LIBVIRT_BEGIN_ALLOW_THREADS;
c_retval = virSecretGetUUIDString(dom, &uuidstr[0]);
LIBVIRT_END_ALLOW_THREADS;
if (c_retval < 0)
return VIR_PY_NONE;
py_retval = PyString_FromString((char *) &uuidstr[0]);
return(py_retval);
}
static PyObject *
libvirt_virSecretLookupByUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_retval;
virSecretPtr c_retval;
virConnectPtr conn;
PyObject *pyobj_conn;
unsigned char * uuid;
int len;
if (!PyArg_ParseTuple(args, (char *)"Oz#:virSecretLookupByUUID", &pyobj_conn, &uuid, &len))
return(NULL);
conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
if ((uuid == NULL) || (len != VIR_UUID_BUFLEN))
return VIR_PY_NONE;
LIBVIRT_BEGIN_ALLOW_THREADS;
c_retval = virSecretLookupByUUID(conn, uuid);
LIBVIRT_END_ALLOW_THREADS;
py_retval = libvirt_virSecretPtrWrap((virSecretPtr) c_retval);
return(py_retval);
}
static PyObject * static PyObject *
libvirt_virConnectListSecrets(PyObject *self ATTRIBUTE_UNUSED, libvirt_virConnectListSecrets(PyObject *self ATTRIBUTE_UNUSED,
PyObject *args) { PyObject *args) {
@ -2358,6 +2434,9 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virEventInvokeTimeoutCallback", libvirt_virEventInvokeTimeoutCallback, METH_VARARGS, NULL}, {(char *) "virEventInvokeTimeoutCallback", libvirt_virEventInvokeTimeoutCallback, METH_VARARGS, NULL},
{(char *) "virNodeListDevices", libvirt_virNodeListDevices, METH_VARARGS, NULL}, {(char *) "virNodeListDevices", libvirt_virNodeListDevices, METH_VARARGS, NULL},
{(char *) "virNodeDeviceListCaps", libvirt_virNodeDeviceListCaps, METH_VARARGS, NULL}, {(char *) "virNodeDeviceListCaps", libvirt_virNodeDeviceListCaps, METH_VARARGS, NULL},
{(char *) "virSecretGetUUID", libvirt_virSecretGetUUID, METH_VARARGS, NULL},
{(char *) "virSecretGetUUIDString", libvirt_virSecretGetUUIDString, METH_VARARGS, NULL},
{(char *) "virSecretLookupByUUID", libvirt_virSecretLookupByUUID, METH_VARARGS, NULL},
{(char *) "virConnectListSecrets", libvirt_virConnectListSecrets, METH_VARARGS, NULL}, {(char *) "virConnectListSecrets", libvirt_virConnectListSecrets, METH_VARARGS, NULL},
{(char *) "virSecretGetValue", libvirt_virSecretGetValue, METH_VARARGS, NULL}, {(char *) "virSecretGetValue", libvirt_virSecretGetValue, METH_VARARGS, NULL},
{(char *) "virSecretSetValue", libvirt_virSecretSetValue, METH_VARARGS, NULL}, {(char *) "virSecretSetValue", libvirt_virSecretSetValue, METH_VARARGS, NULL},

View File

@ -190,5 +190,21 @@
<arg name='value' type='const char *' info='The secret value'/> <arg name='value' type='const char *' info='The secret value'/>
<arg name='flags' type='unsigned int' info='flags (unused; pass 0)'/> <arg name='flags' type='unsigned int' info='flags (unused; pass 0)'/>
</function> </function>
<function name='virSecretLookupByUUID' file='python'>
<info>Try to lookup a secret on the given hypervisor based on its UUID.</info>
<return type='virSecretPtr' info='a new secret object or NULL in case of failure'/>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
<arg name='uuid' type='const unsigned char *' info='the UUID string for the secret, must be 16 bytes'/>
</function>
<function name='virSecretGetUUID' file='python'>
<info>Extract the UUID unique Identifier of a secret.</info>
<return type='char *' info='the 16 bytes string or None in case of error'/>
<arg name='secret' type='virSecretPtr' info='a secret object'/>
</function>
<function name='virSecretGetUUIDString' file='python'>
<info>Fetch globally unique ID of the secret as a string.</info>
<return type='char *' info='the UUID string or None in case of error'/>
<arg name='secret' type='virSecretPtr' info='a secret object'/>
</function>
</symbols> </symbols>
</api> </api>

View File

@ -4710,15 +4710,15 @@ remoteDispatchSecretGetXmlDesc (struct qemud_server *server ATTRIBUTE_UNUSED,
} }
static int static int
remoteDispatchSecretLookupByUuidString (struct qemud_server *server ATTRIBUTE_UNUSED, remoteDispatchSecretLookupByUuid (struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_client *client ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED,
virConnectPtr conn, remote_error *err, virConnectPtr conn, remote_error *err,
remote_secret_lookup_by_uuid_string_args *args, remote_secret_lookup_by_uuid_args *args,
remote_secret_lookup_by_uuid_string_ret *ret) remote_secret_lookup_by_uuid_ret *ret)
{ {
virSecretPtr secret; virSecretPtr secret;
secret = virSecretLookupByUUIDString (conn, args->uuid); secret = virSecretLookupByUUID (conn, (unsigned char *)args->uuid);
if (secret == NULL) { if (secret == NULL) {
remoteDispatchConnError (err, conn); remoteDispatchConnError (err, conn);
return -1; return -1;
@ -4828,7 +4828,7 @@ get_nonnull_storage_vol (virConnectPtr conn, remote_nonnull_storage_vol vol)
static virSecretPtr static virSecretPtr
get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret) get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret)
{ {
return virGetSecret (conn, secret.uuid); return virGetSecret (conn, BAD_CAST secret.uuid);
} }
/* Make remote_nonnull_domain and remote_nonnull_network. */ /* Make remote_nonnull_domain and remote_nonnull_network. */
@ -4879,5 +4879,5 @@ make_nonnull_node_device (remote_nonnull_node_device *dev_dst, virNodeDevicePtr
static void static void
make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src) make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src)
{ {
secret_dst->uuid = strdup(secret_src->uuid); memcpy (secret_dst->uuid, secret_src->uuid, VIR_UUID_BUFLEN);
} }

View File

@ -118,7 +118,7 @@
remote_domain_xml_to_native_args val_remote_domain_xml_to_native_args; remote_domain_xml_to_native_args val_remote_domain_xml_to_native_args;
remote_list_defined_interfaces_args val_remote_list_defined_interfaces_args; remote_list_defined_interfaces_args val_remote_list_defined_interfaces_args;
remote_list_secrets_args val_remote_list_secrets_args; remote_list_secrets_args val_remote_list_secrets_args;
remote_secret_lookup_by_uuid_string_args val_remote_secret_lookup_by_uuid_string_args; remote_secret_lookup_by_uuid_args val_remote_secret_lookup_by_uuid_args;
remote_secret_define_xml_args val_remote_secret_define_xml_args; remote_secret_define_xml_args val_remote_secret_define_xml_args;
remote_secret_get_xml_desc_args val_remote_secret_get_xml_desc_args; remote_secret_get_xml_desc_args val_remote_secret_get_xml_desc_args;
remote_secret_set_value_args val_remote_secret_set_value_args; remote_secret_set_value_args val_remote_secret_set_value_args;

View File

@ -807,13 +807,13 @@ static int remoteDispatchSecretGetXmlDesc(
remote_error *err, remote_error *err,
remote_secret_get_xml_desc_args *args, remote_secret_get_xml_desc_args *args,
remote_secret_get_xml_desc_ret *ret); remote_secret_get_xml_desc_ret *ret);
static int remoteDispatchSecretLookupByUuidString( static int remoteDispatchSecretLookupByUuid(
struct qemud_server *server, struct qemud_server *server,
struct qemud_client *client, struct qemud_client *client,
virConnectPtr conn, virConnectPtr conn,
remote_error *err, remote_error *err,
remote_secret_lookup_by_uuid_string_args *args, remote_secret_lookup_by_uuid_args *args,
remote_secret_lookup_by_uuid_string_ret *ret); remote_secret_lookup_by_uuid_ret *ret);
static int remoteDispatchSecretSetValue( static int remoteDispatchSecretSetValue(
struct qemud_server *server, struct qemud_server *server,
struct qemud_client *client, struct qemud_client *client,

View File

@ -101,7 +101,7 @@
remote_list_defined_interfaces_ret val_remote_list_defined_interfaces_ret; remote_list_defined_interfaces_ret val_remote_list_defined_interfaces_ret;
remote_num_of_secrets_ret val_remote_num_of_secrets_ret; remote_num_of_secrets_ret val_remote_num_of_secrets_ret;
remote_list_secrets_ret val_remote_list_secrets_ret; remote_list_secrets_ret val_remote_list_secrets_ret;
remote_secret_lookup_by_uuid_string_ret val_remote_secret_lookup_by_uuid_string_ret; remote_secret_lookup_by_uuid_ret val_remote_secret_lookup_by_uuid_ret;
remote_secret_define_xml_ret val_remote_secret_define_xml_ret; remote_secret_define_xml_ret val_remote_secret_define_xml_ret;
remote_secret_get_xml_desc_ret val_remote_secret_get_xml_desc_ret; remote_secret_get_xml_desc_ret val_remote_secret_get_xml_desc_ret;
remote_secret_get_value_ret val_remote_secret_get_value_ret; remote_secret_get_value_ret val_remote_secret_get_value_ret;

View File

@ -707,10 +707,10 @@
.args_filter = (xdrproc_t) xdr_remote_list_secrets_args, .args_filter = (xdrproc_t) xdr_remote_list_secrets_args,
.ret_filter = (xdrproc_t) xdr_remote_list_secrets_ret, .ret_filter = (xdrproc_t) xdr_remote_list_secrets_ret,
}, },
{ /* SecretLookupByUuidString => 141 */ { /* SecretLookupByUuid => 141 */
.fn = (dispatch_fn) remoteDispatchSecretLookupByUuidString, .fn = (dispatch_fn) remoteDispatchSecretLookupByUuid,
.args_filter = (xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_args, .args_filter = (xdrproc_t) xdr_remote_secret_lookup_by_uuid_args,
.ret_filter = (xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_ret, .ret_filter = (xdrproc_t) xdr_remote_secret_lookup_by_uuid_ret,
}, },
{ /* SecretDefineXml => 142 */ { /* SecretDefineXml => 142 */
.fn = (dispatch_fn) remoteDispatchSecretDefineXml, .fn = (dispatch_fn) remoteDispatchSecretDefineXml,

View File

@ -107,7 +107,7 @@ bool_t
xdr_remote_nonnull_secret (XDR *xdrs, remote_nonnull_secret *objp) xdr_remote_nonnull_secret (XDR *xdrs, remote_nonnull_secret *objp)
{ {
if (!xdr_remote_nonnull_string (xdrs, &objp->uuid)) if (!xdr_remote_uuid (xdrs, objp->uuid))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
@ -2572,16 +2572,16 @@ xdr_remote_list_secrets_ret (XDR *xdrs, remote_list_secrets_ret *objp)
} }
bool_t bool_t
xdr_remote_secret_lookup_by_uuid_string_args (XDR *xdrs, remote_secret_lookup_by_uuid_string_args *objp) xdr_remote_secret_lookup_by_uuid_args (XDR *xdrs, remote_secret_lookup_by_uuid_args *objp)
{ {
if (!xdr_remote_nonnull_string (xdrs, &objp->uuid)) if (!xdr_remote_uuid (xdrs, objp->uuid))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
bool_t bool_t
xdr_remote_secret_lookup_by_uuid_string_ret (XDR *xdrs, remote_secret_lookup_by_uuid_string_ret *objp) xdr_remote_secret_lookup_by_uuid_ret (XDR *xdrs, remote_secret_lookup_by_uuid_ret *objp)
{ {
if (!xdr_remote_nonnull_secret (xdrs, &objp->secret)) if (!xdr_remote_nonnull_secret (xdrs, &objp->secret))

View File

@ -86,7 +86,7 @@ struct remote_nonnull_node_device {
typedef struct remote_nonnull_node_device remote_nonnull_node_device; typedef struct remote_nonnull_node_device remote_nonnull_node_device;
struct remote_nonnull_secret { struct remote_nonnull_secret {
remote_nonnull_string uuid; remote_uuid uuid;
}; };
typedef struct remote_nonnull_secret remote_nonnull_secret; typedef struct remote_nonnull_secret remote_nonnull_secret;
@ -1453,15 +1453,15 @@ struct remote_list_secrets_ret {
}; };
typedef struct remote_list_secrets_ret remote_list_secrets_ret; typedef struct remote_list_secrets_ret remote_list_secrets_ret;
struct remote_secret_lookup_by_uuid_string_args { struct remote_secret_lookup_by_uuid_args {
remote_nonnull_string uuid; remote_uuid uuid;
}; };
typedef struct remote_secret_lookup_by_uuid_string_args remote_secret_lookup_by_uuid_string_args; typedef struct remote_secret_lookup_by_uuid_args remote_secret_lookup_by_uuid_args;
struct remote_secret_lookup_by_uuid_string_ret { struct remote_secret_lookup_by_uuid_ret {
remote_nonnull_secret secret; remote_nonnull_secret secret;
}; };
typedef struct remote_secret_lookup_by_uuid_string_ret remote_secret_lookup_by_uuid_string_ret; typedef struct remote_secret_lookup_by_uuid_ret remote_secret_lookup_by_uuid_ret;
struct remote_secret_define_xml_args { struct remote_secret_define_xml_args {
remote_nonnull_string xml; remote_nonnull_string xml;
@ -1657,7 +1657,7 @@ enum remote_procedure {
REMOTE_PROC_LIST_DEFINED_INTERFACES = 138, REMOTE_PROC_LIST_DEFINED_INTERFACES = 138,
REMOTE_PROC_NUM_OF_SECRETS = 139, REMOTE_PROC_NUM_OF_SECRETS = 139,
REMOTE_PROC_LIST_SECRETS = 140, REMOTE_PROC_LIST_SECRETS = 140,
REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING = 141, REMOTE_PROC_SECRET_LOOKUP_BY_UUID = 141,
REMOTE_PROC_SECRET_DEFINE_XML = 142, REMOTE_PROC_SECRET_DEFINE_XML = 142,
REMOTE_PROC_SECRET_GET_XML_DESC = 143, REMOTE_PROC_SECRET_GET_XML_DESC = 143,
REMOTE_PROC_SECRET_SET_VALUE = 144, REMOTE_PROC_SECRET_SET_VALUE = 144,
@ -1929,8 +1929,8 @@ extern bool_t xdr_remote_domain_xml_to_native_ret (XDR *, remote_domain_xml_to_
extern bool_t xdr_remote_num_of_secrets_ret (XDR *, remote_num_of_secrets_ret*); extern bool_t xdr_remote_num_of_secrets_ret (XDR *, remote_num_of_secrets_ret*);
extern bool_t xdr_remote_list_secrets_args (XDR *, remote_list_secrets_args*); extern bool_t xdr_remote_list_secrets_args (XDR *, remote_list_secrets_args*);
extern bool_t xdr_remote_list_secrets_ret (XDR *, remote_list_secrets_ret*); extern bool_t xdr_remote_list_secrets_ret (XDR *, remote_list_secrets_ret*);
extern bool_t xdr_remote_secret_lookup_by_uuid_string_args (XDR *, remote_secret_lookup_by_uuid_string_args*); extern bool_t xdr_remote_secret_lookup_by_uuid_args (XDR *, remote_secret_lookup_by_uuid_args*);
extern bool_t xdr_remote_secret_lookup_by_uuid_string_ret (XDR *, remote_secret_lookup_by_uuid_string_ret*); extern bool_t xdr_remote_secret_lookup_by_uuid_ret (XDR *, remote_secret_lookup_by_uuid_ret*);
extern bool_t xdr_remote_secret_define_xml_args (XDR *, remote_secret_define_xml_args*); extern bool_t xdr_remote_secret_define_xml_args (XDR *, remote_secret_define_xml_args*);
extern bool_t xdr_remote_secret_define_xml_ret (XDR *, remote_secret_define_xml_ret*); extern bool_t xdr_remote_secret_define_xml_ret (XDR *, remote_secret_define_xml_ret*);
extern bool_t xdr_remote_secret_get_xml_desc_args (XDR *, remote_secret_get_xml_desc_args*); extern bool_t xdr_remote_secret_get_xml_desc_args (XDR *, remote_secret_get_xml_desc_args*);
@ -2181,8 +2181,8 @@ extern bool_t xdr_remote_domain_xml_to_native_ret ();
extern bool_t xdr_remote_num_of_secrets_ret (); extern bool_t xdr_remote_num_of_secrets_ret ();
extern bool_t xdr_remote_list_secrets_args (); extern bool_t xdr_remote_list_secrets_args ();
extern bool_t xdr_remote_list_secrets_ret (); extern bool_t xdr_remote_list_secrets_ret ();
extern bool_t xdr_remote_secret_lookup_by_uuid_string_args (); extern bool_t xdr_remote_secret_lookup_by_uuid_args ();
extern bool_t xdr_remote_secret_lookup_by_uuid_string_ret (); extern bool_t xdr_remote_secret_lookup_by_uuid_ret ();
extern bool_t xdr_remote_secret_define_xml_args (); extern bool_t xdr_remote_secret_define_xml_args ();
extern bool_t xdr_remote_secret_define_xml_ret (); extern bool_t xdr_remote_secret_define_xml_ret ();
extern bool_t xdr_remote_secret_get_xml_desc_args (); extern bool_t xdr_remote_secret_get_xml_desc_args ();

View File

@ -188,7 +188,7 @@ struct remote_nonnull_node_device {
/* A secret which may not be null. */ /* A secret which may not be null. */
struct remote_nonnull_secret { struct remote_nonnull_secret {
remote_nonnull_string uuid; remote_uuid uuid;
}; };
/* A domain or network which may be NULL. */ /* A domain or network which may be NULL. */
@ -1293,11 +1293,11 @@ struct remote_list_secrets_ret {
remote_nonnull_string uuids<REMOTE_SECRET_UUID_LIST_MAX>; remote_nonnull_string uuids<REMOTE_SECRET_UUID_LIST_MAX>;
}; };
struct remote_secret_lookup_by_uuid_string_args { struct remote_secret_lookup_by_uuid_args {
remote_nonnull_string uuid; remote_uuid uuid;
}; };
struct remote_secret_lookup_by_uuid_string_ret { struct remote_secret_lookup_by_uuid_ret {
remote_nonnull_secret secret; remote_nonnull_secret secret;
}; };
@ -1500,7 +1500,7 @@ enum remote_procedure {
REMOTE_PROC_NUM_OF_SECRETS = 139, REMOTE_PROC_NUM_OF_SECRETS = 139,
REMOTE_PROC_LIST_SECRETS = 140, REMOTE_PROC_LIST_SECRETS = 140,
REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING = 141, REMOTE_PROC_SECRET_LOOKUP_BY_UUID = 141,
REMOTE_PROC_SECRET_DEFINE_XML = 142, REMOTE_PROC_SECRET_DEFINE_XML = 142,
REMOTE_PROC_SECRET_GET_XML_DESC = 143, REMOTE_PROC_SECRET_GET_XML_DESC = 143,
REMOTE_PROC_SECRET_SET_VALUE = 144, REMOTE_PROC_SECRET_SET_VALUE = 144,

View File

@ -25,6 +25,7 @@
#include "virterror_internal.h" #include "virterror_internal.h"
#include "logging.h" #include "logging.h"
#include "memory.h" #include "memory.h"
#include "uuid.h"
#define VIR_FROM_THIS VIR_FROM_NONE #define VIR_FROM_THIS VIR_FROM_NONE
@ -1169,9 +1170,10 @@ virUnrefNodeDevice(virNodeDevicePtr dev) {
* Returns a pointer to the secret, or NULL in case of failure * Returns a pointer to the secret, or NULL in case of failure
*/ */
virSecretPtr virSecretPtr
virGetSecret(virConnectPtr conn, const char *uuid) virGetSecret(virConnectPtr conn, const unsigned char *uuid)
{ {
virSecretPtr ret = NULL; virSecretPtr ret = NULL;
char uuidstr[VIR_UUID_STRING_BUFLEN];
if (!VIR_IS_CONNECT(conn) || uuid == NULL) { if (!VIR_IS_CONNECT(conn) || uuid == NULL) {
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
@ -1179,7 +1181,9 @@ virGetSecret(virConnectPtr conn, const char *uuid)
} }
virMutexLock(&conn->lock); virMutexLock(&conn->lock);
ret = virHashLookup(conn->secrets, uuid); virUUIDFormat(uuid, uuidstr);
ret = virHashLookup(conn->secrets, uuidstr);
if (ret == NULL) { if (ret == NULL) {
if (VIR_ALLOC(ret) < 0) { if (VIR_ALLOC(ret) < 0) {
virMutexUnlock(&conn->lock); virMutexUnlock(&conn->lock);
@ -1188,14 +1192,9 @@ virGetSecret(virConnectPtr conn, const char *uuid)
} }
ret->magic = VIR_SECRET_MAGIC; ret->magic = VIR_SECRET_MAGIC;
ret->conn = conn; ret->conn = conn;
ret->uuid = strdup(uuid); memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
if (ret->uuid == NULL) {
virMutexUnlock(&conn->lock);
virReportOOMError(conn);
goto error;
}
if (virHashAddEntry(conn->secrets, uuid, ret) < 0) { if (virHashAddEntry(conn->secrets, uuidstr, ret) < 0) {
virMutexUnlock(&conn->lock); virMutexUnlock(&conn->lock);
virLibConnError(conn, VIR_ERR_INTERNAL_ERROR, virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("failed to add secret to conn hash table")); "%s", _("failed to add secret to conn hash table"));
@ -1229,9 +1228,11 @@ error:
static void static void
virReleaseSecret(virSecretPtr secret) { virReleaseSecret(virSecretPtr secret) {
virConnectPtr conn = secret->conn; virConnectPtr conn = secret->conn;
DEBUG("release secret %p %s", secret, secret->uuid); char uuidstr[VIR_UUID_STRING_BUFLEN];
DEBUG("release secret %p %p", secret, secret->uuid);
if (virHashRemoveEntry(conn->secrets, secret->uuid, NULL) < 0) { virUUIDFormat(secret->uuid, uuidstr);
if (virHashRemoveEntry(conn->secrets, uuidstr, NULL) < 0) {
virMutexUnlock(&conn->lock); virMutexUnlock(&conn->lock);
virLibConnError(conn, VIR_ERR_INTERNAL_ERROR, virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("secret missing from connection hash table")); "%s", _("secret missing from connection hash table"));
@ -1239,7 +1240,6 @@ virReleaseSecret(virSecretPtr secret) {
} }
secret->magic = -1; secret->magic = -1;
VIR_FREE(secret->uuid);
VIR_FREE(secret); VIR_FREE(secret);
if (conn) { if (conn) {
@ -1272,7 +1272,7 @@ virUnrefSecret(virSecretPtr secret) {
return -1; return -1;
} }
virMutexLock(&secret->conn->lock); virMutexLock(&secret->conn->lock);
DEBUG("unref secret %p %s %d", secret, secret->uuid, secret->refs); DEBUG("unref secret %p %p %d", secret, secret->uuid, secret->refs);
secret->refs--; secret->refs--;
refs = secret->refs; refs = secret->refs;
if (refs == 0) { if (refs == 0) {

View File

@ -255,7 +255,7 @@ struct _virSecret {
unsigned int magic; /* specific value to check */ unsigned int magic; /* specific value to check */
int refs; /* reference count */ int refs; /* reference count */
virConnectPtr conn; /* pointer back to the connection */ virConnectPtr conn; /* pointer back to the connection */
char *uuid; /* ID of the secret */ unsigned char uuid[VIR_UUID_BUFLEN]; /* the domain unique identifier */
}; };
@ -296,7 +296,7 @@ virNodeDevicePtr virGetNodeDevice(virConnectPtr conn,
int virUnrefNodeDevice(virNodeDevicePtr dev); int virUnrefNodeDevice(virNodeDevicePtr dev);
virSecretPtr virGetSecret(virConnectPtr conn, virSecretPtr virGetSecret(virConnectPtr conn,
const char *uuid); const unsigned char *uuid);
int virUnrefSecret(virSecretPtr secret); int virUnrefSecret(virSecretPtr secret);
#endif #endif

View File

@ -819,8 +819,8 @@ verify((VIR_SECRET_GET_VALUE_INTERNAL_CALL &
VIR_SECRET_GET_VALUE_FLAGS_MASK) == 0); VIR_SECRET_GET_VALUE_FLAGS_MASK) == 0);
typedef virSecretPtr typedef virSecretPtr
(*virDrvSecretLookupByUUIDString) (virConnectPtr conn, (*virDrvSecretLookupByUUID) (virConnectPtr conn,
const char *uuid); const unsigned char *uuid);
typedef virSecretPtr typedef virSecretPtr
(*virDrvSecretDefineXML) (virConnectPtr conn, (*virDrvSecretDefineXML) (virConnectPtr conn,
const char *xml, const char *xml,
@ -866,7 +866,7 @@ struct _virSecretDriver {
virDrvSecretNumOfSecrets numOfSecrets; virDrvSecretNumOfSecrets numOfSecrets;
virDrvSecretListSecrets listSecrets; virDrvSecretListSecrets listSecrets;
virDrvSecretLookupByUUIDString lookupByUUIDString; virDrvSecretLookupByUUID lookupByUUID;
virDrvSecretDefineXML defineXML; virDrvSecretDefineXML defineXML;
virDrvSecretGetXMLDesc getXMLDesc; virDrvSecretGetXMLDesc getXMLDesc;
virDrvSecretSetValue setValue; virDrvSecretSetValue setValue;

View File

@ -8811,36 +8811,37 @@ error:
} }
/** /**
* virSecretLookupByUUIDString: * virSecretLookupByUUID:
* @conn: virConnect connection * @conn: pointer to the hypervisor connection
* @uuid: ID of a secret * @uuid: the raw UUID for the secret
* *
* Fetches a secret based on uuid. * Try to lookup a secret on the given hypervisor based on its UUID.
* Uses the 16 bytes of raw data to describe the UUID
* *
* Returns the secret on success, or NULL on failure. * Returns a new secret object or NULL in case of failure. If the
* secret cannot be found, then VIR_ERR_NO_SECRET error is raised.
*/ */
virSecretPtr virSecretPtr
virSecretLookupByUUIDString(virConnectPtr conn, const char *uuid) virSecretLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{ {
VIR_DEBUG("conn=%p, uuid=%s", conn, uuid); DEBUG("conn=%p, uuid=%s", conn, uuid);
virResetLastError(); virResetLastError();
if (!VIR_IS_CONNECT(conn)) { if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return NULL; return (NULL);
} }
if (uuid == NULL) { if (uuid == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error; goto error;
} }
if (conn->secretDriver != NULL && if (conn->secretDriver &&
conn->secretDriver->lookupByUUIDString != NULL) { conn->secretDriver->lookupByUUID) {
virSecretPtr ret; virSecretPtr ret;
ret = conn->secretDriver->lookupByUUID (conn, uuid);
ret = conn->secretDriver->lookupByUUIDString(conn, uuid); if (!ret)
if (ret == NULL)
goto error; goto error;
return ret; return ret;
} }
@ -8853,6 +8854,66 @@ error:
return NULL; return NULL;
} }
/**
* virSecretLookupByUUIDString:
* @conn: pointer to the hypervisor connection
* @uuidstr: the string UUID for the secret
*
* Try to lookup a secret on the given hypervisor based on its UUID.
* Uses the printable string value to describe the UUID
*
* Returns a new secret object or NULL in case of failure. If the
* secret cannot be found, then VIR_ERR_NO_SECRET error is raised.
*/
virSecretPtr
virSecretLookupByUUIDString(virConnectPtr conn, const char *uuidstr)
{
int raw[VIR_UUID_BUFLEN], i;
unsigned char uuid[VIR_UUID_BUFLEN];
int ret;
DEBUG("conn=%p, uuidstr=%s", conn, uuidstr);
virResetLastError();
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (uuidstr == NULL) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
/* XXX: sexpr_uuid() also supports 'xxxx-xxxx-xxxx-xxxx' format.
* We needn't it here. Right?
*/
ret = sscanf(uuidstr,
"%02x%02x%02x%02x-"
"%02x%02x-"
"%02x%02x-"
"%02x%02x-"
"%02x%02x%02x%02x%02x%02x",
raw + 0, raw + 1, raw + 2, raw + 3,
raw + 4, raw + 5, raw + 6, raw + 7,
raw + 8, raw + 9, raw + 10, raw + 11,
raw + 12, raw + 13, raw + 14, raw + 15);
if (ret!=VIR_UUID_BUFLEN) {
virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
for (i = 0; i < VIR_UUID_BUFLEN; i++)
uuid[i] = raw[i] & 0xFF;
return virSecretLookupByUUID(conn, &uuid[0]);
error:
/* Copy to connection error object for back compatability */
virSetConnError(conn);
return NULL;
}
/** /**
* virSecretDefineXML: * virSecretDefineXML:
* @conn: virConnect connection * @conn: virConnect connection
@ -8906,37 +8967,78 @@ error:
} }
/** /**
* virSecretGetUUIDString: * virSecretGetUUID:
* @secret: A virSecret secret * @secret: A virSecret secret
* @uuid: buffer of VIR_UUID_BUFLEN bytes in size
* *
* Fetches the UUID of the secret. * Fetches the UUID of the secret.
* *
* Returns ID of the secret (not necessarily in the UUID format) on success, * Returns 0 on success with the uuid buffer being filled, or
* NULL on failure. The caller must free() the ID. * -1 upon failure.
*/ */
char * int
virSecretGetUUIDString(virSecretPtr secret) virSecretGetUUID(virSecretPtr secret, unsigned char *uuid)
{ {
char *ret;
VIR_DEBUG("secret=%p", secret); VIR_DEBUG("secret=%p", secret);
virResetLastError(); virResetLastError();
if (!VIR_IS_CONNECTED_SECRET(secret)) { if (!VIR_IS_CONNECTED_SECRET(secret)) {
virLibSecretError(NULL, VIR_ERR_INVALID_SECRET, __FUNCTION__); virLibSecretError(NULL, VIR_ERR_INVALID_SECRET, __FUNCTION__);
return NULL; return -1;
}
if (uuid == NULL) {
virLibSecretError(secret, VIR_ERR_INVALID_ARG, __FUNCTION__);
/* Copy to connection error object for back compatability */
virSetConnError(secret->conn);
return -1;
} }
ret = strdup(secret->uuid); memcpy(uuid, &secret->uuid[0], VIR_UUID_BUFLEN);
if (ret != NULL)
return ret;
virReportOOMError(secret->conn); return 0;
virSetConnError(secret->conn);
return NULL;
} }
/**
* virSecretGetUUIDString:
* @secret: a secret object
* @buf: pointer to a VIR_UUID_STRING_BUFLEN bytes array
*
* Get the UUID for a secret as string. For more information about
* UUID see RFC4122.
*
* Returns -1 in case of error, 0 in case of success
*/
int
virSecretGetUUIDString(virSecretPtr secret, char *buf)
{
unsigned char uuid[VIR_UUID_BUFLEN];
DEBUG("secret=%p, buf=%p", secret, buf);
virResetLastError();
if (!VIR_IS_SECRET(secret)) {
virLibSecretError(NULL, VIR_ERR_INVALID_SECRET, __FUNCTION__);
return (-1);
}
if (buf == NULL) {
virLibSecretError(secret, VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
if (virSecretGetUUID(secret, &uuid[0]))
goto error;
virUUIDFormat(uuid, buf);
return (0);
error:
/* Copy to connection error object for back compatability */
virSetConnError(secret->conn);
return -1;
}
/** /**
* virSecretGetXMLDesc: * virSecretGetXMLDesc:
* @secret: A virSecret secret * @secret: A virSecret secret

View File

@ -298,8 +298,10 @@ LIBVIRT_0.7.1 {
virSecretGetConnect; virSecretGetConnect;
virConnectNumOfSecrets; virConnectNumOfSecrets;
virConnectListSecrets; virConnectListSecrets;
virSecretLookupByUUID;
virSecretLookupByUUIDString; virSecretLookupByUUIDString;
virSecretDefineXML; virSecretDefineXML;
virSecretGetUUID;
virSecretGetUUIDString; virSecretGetUUIDString;
virSecretGetXMLDesc; virSecretGetXMLDesc;
virSecretSetValue; virSecretSetValue;

View File

@ -2692,7 +2692,7 @@ findVolumeQcowPassphrase(virConnectPtr conn, virDomainObjPtr vm,
size_t size; size_t size;
if (conn->secretDriver == NULL || if (conn->secretDriver == NULL ||
conn->secretDriver->lookupByUUIDString == NULL || conn->secretDriver->lookupByUUID == NULL ||
conn->secretDriver->getValue == NULL) { conn->secretDriver->getValue == NULL) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, "%s", qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, "%s",
_("secret storage not supported")); _("secret storage not supported"));
@ -2712,13 +2712,8 @@ findVolumeQcowPassphrase(virConnectPtr conn, virDomainObjPtr vm,
return NULL; return NULL;
} }
if (enc->secrets[0]->uuid == NULL) { secret = conn->secretDriver->lookupByUUID(conn,
qemudReportError(conn, NULL, NULL, VIR_ERR_INVALID_DOMAIN, enc->secrets[0]->uuid);
_("missing secret uuid for volume %s"), path);
return NULL;
}
secret = conn->secretDriver->lookupByUUIDString(conn,
enc->secrets[0]->uuid);
if (secret == NULL) if (secret == NULL)
return NULL; return NULL;
data = conn->secretDriver->getValue(secret, &size, data = conn->secretDriver->getValue(secret, &size,

View File

@ -6475,25 +6475,25 @@ done:
} }
static virSecretPtr static virSecretPtr
remoteSecretLookupByUUIDString (virConnectPtr conn, const char *uuid) remoteSecretLookupByUUID (virConnectPtr conn, const unsigned char *uuid)
{ {
virSecretPtr rv = NULL; virSecretPtr rv = NULL;
remote_secret_lookup_by_uuid_string_args args; remote_secret_lookup_by_uuid_args args;
remote_secret_lookup_by_uuid_string_ret ret; remote_secret_lookup_by_uuid_ret ret;
struct private_data *priv = conn->secretPrivateData; struct private_data *priv = conn->secretPrivateData;
remoteDriverLock (priv); remoteDriverLock (priv);
args.uuid = (char *) uuid; memcpy (args.uuid, uuid, VIR_UUID_BUFLEN);
memset (&ret, 0, sizeof (ret)); memset (&ret, 0, sizeof (ret));
if (call (conn, priv, 0, REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING, if (call (conn, priv, 0, REMOTE_PROC_SECRET_LOOKUP_BY_UUID,
(xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_args, (char *) &args, (xdrproc_t) xdr_remote_secret_lookup_by_uuid_args, (char *) &args,
(xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_ret, (char *) &ret) == -1) (xdrproc_t) xdr_remote_secret_lookup_by_uuid_ret, (char *) &ret) == -1)
goto done; goto done;
rv = get_nonnull_secret (conn, ret.secret); rv = get_nonnull_secret (conn, ret.secret);
xdr_free ((xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_ret, xdr_free ((xdrproc_t) xdr_remote_secret_lookup_by_uuid_ret,
(char *) &ret); (char *) &ret);
done: done:
@ -6506,7 +6506,7 @@ remoteSecretDefineXML (virConnectPtr conn, const char *xml, unsigned int flags)
{ {
virSecretPtr rv = NULL; virSecretPtr rv = NULL;
remote_secret_define_xml_args args; remote_secret_define_xml_args args;
remote_secret_lookup_by_uuid_string_ret ret; remote_secret_define_xml_ret ret;
struct private_data *priv = conn->secretPrivateData; struct private_data *priv = conn->secretPrivateData;
remoteDriverLock (priv); remoteDriverLock (priv);
@ -6521,7 +6521,7 @@ remoteSecretDefineXML (virConnectPtr conn, const char *xml, unsigned int flags)
goto done; goto done;
rv = get_nonnull_secret (conn, ret.secret); rv = get_nonnull_secret (conn, ret.secret);
xdr_free ((xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_ret, xdr_free ((xdrproc_t) xdr_remote_secret_define_xml_ret,
(char *) &ret); (char *) &ret);
done: done:
@ -7733,7 +7733,7 @@ get_nonnull_node_device (virConnectPtr conn, remote_nonnull_node_device dev)
static virSecretPtr static virSecretPtr
get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret) get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret)
{ {
return virGetSecret(conn, secret.uuid); return virGetSecret(conn, BAD_CAST secret.uuid);
} }
/* Make remote_nonnull_domain and remote_nonnull_network. */ /* Make remote_nonnull_domain and remote_nonnull_network. */
@ -7778,7 +7778,7 @@ make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr
static void static void
make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src) make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src)
{ {
secret_dst->uuid = secret_src->uuid; memcpy (secret_dst->uuid, secret_src->uuid, VIR_UUID_BUFLEN);
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
@ -7940,7 +7940,7 @@ static virSecretDriver secret_driver = {
.close = remoteSecretClose, .close = remoteSecretClose,
.numOfSecrets = remoteSecretNumOfSecrets, .numOfSecrets = remoteSecretNumOfSecrets,
.listSecrets = remoteSecretListSecrets, .listSecrets = remoteSecretListSecrets,
.lookupByUUIDString = remoteSecretLookupByUUIDString, .lookupByUUID = remoteSecretLookupByUUID,
.defineXML = remoteSecretDefineXML, .defineXML = remoteSecretDefineXML,
.getXMLDesc = remoteSecretGetXMLDesc, .getXMLDesc = remoteSecretGetXMLDesc,
.setValue = remoteSecretSetValue, .setValue = remoteSecretSetValue,

View File

@ -31,6 +31,7 @@
#include "virterror_internal.h" #include "virterror_internal.h"
#include "util.h" #include "util.h"
#include "xml.h" #include "xml.h"
#include "uuid.h"
#define VIR_FROM_THIS VIR_FROM_SECRET #define VIR_FROM_THIS VIR_FROM_SECRET
@ -42,7 +43,6 @@ virSecretDefFree(virSecretDefPtr def)
if (def == NULL) if (def == NULL)
return; return;
VIR_FREE(def->id);
VIR_FREE(def->description); VIR_FREE(def->description);
switch (def->usage_type) { switch (def->usage_type) {
case VIR_SECRET_USAGE_TYPE_NONE: case VIR_SECRET_USAGE_TYPE_NONE:
@ -105,6 +105,7 @@ secretXMLParseNode(virConnectPtr conn, xmlDocPtr xml, xmlNodePtr root)
xmlXPathContextPtr ctxt = NULL; xmlXPathContextPtr ctxt = NULL;
virSecretDefPtr def = NULL, ret = NULL; virSecretDefPtr def = NULL, ret = NULL;
char *prop = NULL; char *prop = NULL;
char *uuidstr = NULL;
if (!xmlStrEqual(root->name, BAD_CAST "secret")) { if (!xmlStrEqual(root->name, BAD_CAST "secret")) {
virSecretReportError(conn, VIR_ERR_XML_ERROR, "%s", virSecretReportError(conn, VIR_ERR_XML_ERROR, "%s",
@ -152,7 +153,22 @@ secretXMLParseNode(virConnectPtr conn, xmlDocPtr xml, xmlNodePtr root)
VIR_FREE(prop); VIR_FREE(prop);
} }
def->id = virXPathString(conn, "string(./uuid)", ctxt); uuidstr = virXPathString(conn, "string(./uuid)", ctxt);
if (!uuidstr) {
if (virUUIDGenerate(def->uuid)) {
virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("Failed to generate UUID"));
goto cleanup;
}
} else {
if (virUUIDParse(uuidstr, def->uuid) < 0) {
virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("malformed uuid element"));
goto cleanup;
}
VIR_FREE(uuidstr);
}
def->description = virXPathString(conn, "string(./description)", ctxt); def->description = virXPathString(conn, "string(./description)", ctxt);
if (virXPathNode(conn, "./usage", ctxt) != NULL if (virXPathNode(conn, "./usage", ctxt) != NULL
&& virSecretDefParseUsage(conn, ctxt, def) < 0) && virSecretDefParseUsage(conn, ctxt, def) < 0)
@ -280,13 +296,17 @@ char *
virSecretDefFormat(virConnectPtr conn, const virSecretDefPtr def) virSecretDefFormat(virConnectPtr conn, const virSecretDefPtr def)
{ {
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
unsigned char *uuid;
char uuidstr[VIR_UUID_STRING_BUFLEN];
char *tmp; char *tmp;
virBufferVSprintf(&buf, "<secret ephemeral='%s' private='%s'>\n", virBufferVSprintf(&buf, "<secret ephemeral='%s' private='%s'>\n",
def->ephemeral ? "yes" : "no", def->ephemeral ? "yes" : "no",
def->private ? "yes" : "no"); def->private ? "yes" : "no");
if (def->id != NULL)
virBufferEscapeString(&buf, " <uuid>%s</uuid>\n", def->id); uuid = def->uuid;
virUUIDFormat(uuid, uuidstr);
virBufferEscapeString(&buf, " <uuid>%s</uuid>\n", uuidstr);
if (def->description != NULL) if (def->description != NULL)
virBufferEscapeString(&buf, " <description>%s</description>\n", virBufferEscapeString(&buf, " <description>%s</description>\n",
def->description); def->description);

View File

@ -43,7 +43,7 @@ typedef virSecretDef *virSecretDefPtr;
struct _virSecretDef { struct _virSecretDef {
unsigned ephemeral : 1; unsigned ephemeral : 1;
unsigned private : 1; unsigned private : 1;
char *id; /* May be NULL */ unsigned char uuid[VIR_UUID_BUFLEN];
char *description; /* May be NULL */ char *description; /* May be NULL */
int usage_type; int usage_type;
union { union {

View File

@ -111,13 +111,13 @@ secretFree(virSecretEntryPtr secret)
} }
static virSecretEntryPtr * static virSecretEntryPtr *
secretFind(virSecretDriverStatePtr driver, const char *uuid) secretFind(virSecretDriverStatePtr driver, const unsigned char *uuid)
{ {
virSecretEntryPtr *pptr, s; virSecretEntryPtr *pptr, s;
for (pptr = &driver->secrets; *pptr != NULL; pptr = &s->next) { for (pptr = &driver->secrets; *pptr != NULL; pptr = &s->next) {
s = *pptr; s = *pptr;
if (STREQ(s->def->id, uuid)) if (memcmp(s->def->uuid, uuid, VIR_UUID_BUFLEN) == 0)
return pptr; return pptr;
} }
return NULL; return NULL;
@ -125,15 +125,13 @@ secretFind(virSecretDriverStatePtr driver, const char *uuid)
static virSecretEntryPtr static virSecretEntryPtr
secretCreate(virConnectPtr conn, virSecretDriverStatePtr driver, secretCreate(virConnectPtr conn, virSecretDriverStatePtr driver,
const char *uuid) const unsigned char *uuid)
{ {
virSecretEntryPtr secret = NULL; virSecretEntryPtr secret = NULL;
if (VIR_ALLOC(secret) < 0 || VIR_ALLOC(secret->def)) if (VIR_ALLOC(secret) < 0 || VIR_ALLOC(secret->def))
goto no_memory; goto no_memory;
secret->def->id = strdup(uuid); memcpy(secret->def->uuid, uuid, VIR_UUID_BUFLEN);
if (secret->def->id == NULL)
goto no_memory;
listInsert(&driver->secrets, secret); listInsert(&driver->secrets, secret);
return secret; return secret;
@ -145,7 +143,7 @@ secretCreate(virConnectPtr conn, virSecretDriverStatePtr driver,
static virSecretEntryPtr static virSecretEntryPtr
secretFindOrCreate(virConnectPtr conn, virSecretDriverStatePtr driver, secretFindOrCreate(virConnectPtr conn, virSecretDriverStatePtr driver,
const char *uuid, bool *created_new) const unsigned char *uuid, bool *created_new)
{ {
virSecretEntryPtr *pptr, secret; virSecretEntryPtr *pptr, secret;
@ -223,18 +221,15 @@ static char *
secretComputePath(virConnectPtr conn, virSecretDriverStatePtr driver, secretComputePath(virConnectPtr conn, virSecretDriverStatePtr driver,
const virSecretEntry *secret, const char *suffix) const virSecretEntry *secret, const char *suffix)
{ {
char *ret, *base64_id; char *ret;
char uuidstr[VIR_UUID_STRING_BUFLEN];
base64_encode_alloc(secret->def->id, strlen(secret->def->id), &base64_id); virUUIDFormat(secret->def->uuid, uuidstr);
if (base64_id == NULL) {
virReportOOMError(conn);
return NULL;
}
if (virAsprintf(&ret, "%s/%s%s", driver->directory, base64_id, suffix) < 0) if (virAsprintf(&ret, "%s/%s%s", driver->directory, uuidstr, suffix) < 0)
/* ret is NULL */ /* ret is NULL */
virReportOOMError(conn); virReportOOMError(conn);
VIR_FREE(base64_id);
return ret; return ret;
} }
@ -357,28 +352,16 @@ static int
secretLoadValidateUUID(virConnectPtr conn, virSecretDefPtr def, secretLoadValidateUUID(virConnectPtr conn, virSecretDefPtr def,
const char *xml_basename) const char *xml_basename)
{ {
char *base64_id; char uuidstr[VIR_UUID_STRING_BUFLEN];
if (def->id == NULL) { virUUIDFormat(def->uuid, uuidstr);
virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("<uuid> missing in secret description in '%s'"),
xml_basename);
return -1;
}
base64_encode_alloc(def->id, strlen(def->id), &base64_id); if (!virFileMatchesNameSuffix(xml_basename, uuidstr, ".xml")) {
if (base64_id == NULL) {
virReportOOMError(conn);
return -1;
}
if (!virFileMatchesNameSuffix(xml_basename, base64_id, ".xml")) {
virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("<uuid> does not match secret file name '%s'"), _("<uuid> does not match secret file name '%s'"),
xml_basename); xml_basename);
VIR_FREE(base64_id);
return -1; return -1;
} }
VIR_FREE(base64_id);
return 0; return 0;
} }
@ -604,11 +587,13 @@ secretListSecrets(virConnectPtr conn, char **uuids, int maxuuids)
i = 0; i = 0;
for (secret = driver->secrets; secret != NULL; secret = secret->next) { for (secret = driver->secrets; secret != NULL; secret = secret->next) {
char *uuidstr;
if (i == maxuuids) if (i == maxuuids)
break; break;
uuids[i] = strdup(secret->def->id); if (VIR_ALLOC_N(uuidstr, VIR_UUID_STRING_BUFLEN) < 0)
if (uuids[i] == NULL)
goto cleanup; goto cleanup;
virUUIDFormat(secret->def->uuid, uuidstr);
uuids[i] = uuidstr;
i++; i++;
} }
@ -625,7 +610,7 @@ cleanup:
} }
static virSecretPtr static virSecretPtr
secretLookupByUUIDString(virConnectPtr conn, const char *uuid) secretLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{ {
virSecretDriverStatePtr driver = conn->secretPrivateData; virSecretDriverStatePtr driver = conn->secretPrivateData;
virSecretPtr ret = NULL; virSecretPtr ret = NULL;
@ -635,49 +620,20 @@ secretLookupByUUIDString(virConnectPtr conn, const char *uuid)
pptr = secretFind(driver, uuid); pptr = secretFind(driver, uuid);
if (pptr == NULL) { if (pptr == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(uuid, uuidstr);
virSecretReportError(conn, VIR_ERR_NO_SECRET, virSecretReportError(conn, VIR_ERR_NO_SECRET,
_("no secret with matching id '%s'"), uuid); _("no secret with matching uuid '%s'"), uuidstr);
goto cleanup; goto cleanup;
} }
ret = virGetSecret(conn, (*pptr)->def->id); ret = virGetSecret(conn, (*pptr)->def->uuid);
cleanup: cleanup:
secretDriverUnlock(driver); secretDriverUnlock(driver);
return ret; return ret;
} }
static char *
secretGenerateUUID(virConnectPtr conn, virSecretDriverStatePtr driver)
{
char *uuid = NULL;
unsigned attempt;
if (VIR_ALLOC_N(uuid, VIR_UUID_STRING_BUFLEN) < 0) {
virReportOOMError(conn);
goto error;
}
for (attempt = 0; attempt < 65536; attempt++) {
unsigned char uuid_data[VIR_UUID_BUFLEN];
if (virUUIDGenerate(uuid_data) < 0) {
virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
_("unable to generate uuid"));
goto error;
}
virUUIDFormat(uuid_data, uuid);
if (secretFind(driver, uuid) == NULL)
return uuid;
}
virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
_("too many conflicts when generating an uuid"));
goto error;
error:
VIR_FREE(uuid);
return NULL;
}
static virSecretPtr static virSecretPtr
secretDefineXML(virConnectPtr conn, const char *xml, secretDefineXML(virConnectPtr conn, const char *xml,
@ -695,16 +651,8 @@ secretDefineXML(virConnectPtr conn, const char *xml,
secretDriverLock(driver); secretDriverLock(driver);
if (new_attrs->id != NULL) secret = secretFindOrCreate(conn, driver, new_attrs->uuid,
secret = secretFindOrCreate(conn, driver, new_attrs->id, &secret_is_new);
&secret_is_new);
else {
new_attrs->id = secretGenerateUUID(conn, driver);
if (new_attrs->id == NULL)
goto cleanup;
secret = secretCreate(conn, driver, new_attrs->id);
secret_is_new = true;
}
if (secret == NULL) if (secret == NULL)
goto cleanup; goto cleanup;
@ -743,7 +691,7 @@ secretDefineXML(virConnectPtr conn, const char *xml,
new_attrs = NULL; new_attrs = NULL;
virSecretDefFree(backup); virSecretDefFree(backup);
ret = virGetSecret(conn, secret->def->id); ret = virGetSecret(conn, secret->def->uuid);
goto cleanup; goto cleanup;
restore_backup: restore_backup:
@ -776,8 +724,10 @@ secretGetXMLDesc(virSecretPtr obj, unsigned int flags ATTRIBUTE_UNUSED)
pptr = secretFind(driver, obj->uuid); pptr = secretFind(driver, obj->uuid);
if (pptr == NULL) { if (pptr == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->uuid, uuidstr);
virSecretReportError(obj->conn, VIR_ERR_NO_SECRET, virSecretReportError(obj->conn, VIR_ERR_NO_SECRET,
_("no secret with matching id '%s'"), obj->uuid); _("no secret with matching uuid '%s'"), uuidstr);
goto cleanup; goto cleanup;
} }
@ -808,8 +758,10 @@ secretSetValue(virSecretPtr obj, const unsigned char *value,
pptr = secretFind(driver, obj->uuid); pptr = secretFind(driver, obj->uuid);
if (pptr == NULL) { if (pptr == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->uuid, uuidstr);
virSecretReportError(obj->conn, VIR_ERR_NO_SECRET, virSecretReportError(obj->conn, VIR_ERR_NO_SECRET,
_("no secret with matching id '%s'"), obj->uuid); _("no secret with matching uuid '%s'"), uuidstr);
goto cleanup; goto cleanup;
} }
secret = *pptr; secret = *pptr;
@ -859,14 +811,18 @@ secretGetValue(virSecretPtr obj, size_t *value_size, unsigned int flags)
pptr = secretFind(driver, obj->uuid); pptr = secretFind(driver, obj->uuid);
if (pptr == NULL) { if (pptr == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->uuid, uuidstr);
virSecretReportError(obj->conn, VIR_ERR_NO_SECRET, virSecretReportError(obj->conn, VIR_ERR_NO_SECRET,
_("no secret with matching id '%s'"), obj->uuid); _("no secret with matching uuid '%s'"), uuidstr);
goto cleanup; goto cleanup;
} }
secret = *pptr; secret = *pptr;
if (secret->value == NULL) { if (secret->value == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->uuid, uuidstr);
virSecretReportError(obj->conn, VIR_ERR_NO_SECRET, virSecretReportError(obj->conn, VIR_ERR_NO_SECRET,
_("secret '%s' does not have a value"), obj->uuid); _("secret '%s' does not have a value"), uuidstr);
goto cleanup; goto cleanup;
} }
@ -901,8 +857,10 @@ secretUndefine(virSecretPtr obj)
pptr = secretFind(driver, obj->uuid); pptr = secretFind(driver, obj->uuid);
if (pptr == NULL) { if (pptr == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->uuid, uuidstr);
virSecretReportError(obj->conn, VIR_ERR_NO_SECRET, virSecretReportError(obj->conn, VIR_ERR_NO_SECRET,
_("no secret with matching id '%s'"), obj->uuid); _("no secret with matching uuid '%s'"), uuidstr);
goto cleanup; goto cleanup;
} }
@ -1036,7 +994,7 @@ static virSecretDriver secretDriver = {
.close = secretClose, .close = secretClose,
.numOfSecrets = secretNumOfSecrets, .numOfSecrets = secretNumOfSecrets,
.listSecrets = secretListSecrets, .listSecrets = secretListSecrets,
.lookupByUUIDString = secretLookupByUUIDString, .lookupByUUID = secretLookupByUUID,
.defineXML = secretDefineXML, .defineXML = secretDefineXML,
.getXMLDesc = secretGetXMLDesc, .getXMLDesc = secretGetXMLDesc,
.setValue = secretSetValue, .setValue = secretSetValue,

View File

@ -50,8 +50,9 @@
#include "node_device.h" #include "node_device.h"
#include "internal.h" #include "internal.h"
#include "secret_conf.h" #include "secret_conf.h"
#include "uuid.h"
#include "storage_backend.h" #include "storage_backend.h"
#include "logging.h"
#if WITH_STORAGE_LVM #if WITH_STORAGE_LVM
#include "storage_backend_logical.h" #include "storage_backend_logical.h"
@ -337,6 +338,32 @@ cleanup:
return ret; return ret;
} }
static int
virStorageGenerateSecretUUID(virConnectPtr conn,
unsigned char *uuid)
{
unsigned attempt;
for (attempt = 0; attempt < 65536; attempt++) {
virSecretPtr tmp;
if (virUUIDGenerate(uuid) < 0) {
virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
_("unable to generate uuid"));
return -1;
}
tmp = conn->secretDriver->lookupByUUID(conn, uuid);
if (tmp == NULL)
return 0;
virSecretFree(tmp);
}
virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
_("too many conflicts when generating an uuid"));
return -1;
}
static int static int
virStorageGenerateQcowEncryption(virConnectPtr conn, virStorageGenerateQcowEncryption(virConnectPtr conn,
virStorageVolDefPtr vol) virStorageVolDefPtr vol)
@ -346,11 +373,13 @@ virStorageGenerateQcowEncryption(virConnectPtr conn,
virStorageEncryptionPtr enc; virStorageEncryptionPtr enc;
virStorageEncryptionSecretPtr enc_secret = NULL; virStorageEncryptionSecretPtr enc_secret = NULL;
virSecretPtr secret = NULL; virSecretPtr secret = NULL;
char *uuid = NULL, *xml; char *xml;
unsigned char value[VIR_STORAGE_QCOW_PASSPHRASE_SIZE]; unsigned char value[VIR_STORAGE_QCOW_PASSPHRASE_SIZE];
int ret = -1; int ret = -1;
if (conn->secretDriver == NULL || conn->secretDriver->defineXML == NULL || if (conn->secretDriver == NULL ||
conn->secretDriver->lookupByUUID == NULL ||
conn->secretDriver->defineXML == NULL ||
conn->secretDriver->setValue == NULL) { conn->secretDriver->setValue == NULL) {
virStorageReportError(conn, VIR_ERR_NO_SUPPORT, "%s", virStorageReportError(conn, VIR_ERR_NO_SUPPORT, "%s",
_("secret storage not supported")); _("secret storage not supported"));
@ -372,12 +401,9 @@ virStorageGenerateQcowEncryption(virConnectPtr conn,
def->ephemeral = 0; def->ephemeral = 0;
def->private = 0; def->private = 0;
def->id = NULL; /* Chosen by the secret driver */ if (virStorageGenerateSecretUUID(conn, def->uuid) < 0)
if (virAsprintf(&def->description, "qcow passphrase for %s",
vol->target.path) == -1) {
virReportOOMError(conn);
goto cleanup; goto cleanup;
}
def->usage_type = VIR_SECRET_USAGE_TYPE_VOLUME; def->usage_type = VIR_SECRET_USAGE_TYPE_VOLUME;
def->usage.volume = strdup(vol->target.path); def->usage.volume = strdup(vol->target.path);
if (def->usage.volume == NULL) { if (def->usage.volume == NULL) {
@ -397,22 +423,14 @@ virStorageGenerateQcowEncryption(virConnectPtr conn,
} }
VIR_FREE(xml); VIR_FREE(xml);
uuid = strdup(secret->uuid);
if (uuid == NULL) {
virReportOOMError(conn);
goto cleanup;
}
if (virStorageGenerateQcowPassphrase(conn, value) < 0) if (virStorageGenerateQcowPassphrase(conn, value) < 0)
goto cleanup; goto cleanup;
if (conn->secretDriver->setValue(secret, value, sizeof(value), 0) < 0) if (conn->secretDriver->setValue(secret, value, sizeof(value), 0) < 0)
goto cleanup; goto cleanup;
secret = NULL;
enc_secret->type = VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE; enc_secret->type = VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE;
enc_secret->uuid = uuid; memcpy(enc_secret->uuid, secret->uuid, VIR_UUID_BUFLEN);
uuid = NULL;
enc->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW; enc->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
enc->secrets[0] = enc_secret; /* Space for secrets[0] allocated above */ enc->secrets[0] = enc_secret; /* Space for secrets[0] allocated above */
enc_secret = NULL; enc_secret = NULL;
@ -421,9 +439,9 @@ virStorageGenerateQcowEncryption(virConnectPtr conn,
ret = 0; ret = 0;
cleanup: cleanup:
VIR_FREE(uuid);
if (secret != NULL) { if (secret != NULL) {
if (conn->secretDriver->undefine != NULL) if (ret != 0 &&
conn->secretDriver->undefine != NULL)
conn->secretDriver->undefine(secret); conn->secretDriver->undefine(secret);
virSecretFree(secret); virSecretFree(secret);
} }

View File

@ -34,6 +34,7 @@
#include "util.h" #include "util.h"
#include "xml.h" #include "xml.h"
#include "virterror_internal.h" #include "virterror_internal.h"
#include "uuid.h"
#define VIR_FROM_THIS VIR_FROM_STORAGE #define VIR_FROM_THIS VIR_FROM_STORAGE
@ -49,7 +50,6 @@ virStorageEncryptionSecretFree(virStorageEncryptionSecretPtr secret)
{ {
if (!secret) if (!secret)
return; return;
VIR_FREE(secret->uuid);
VIR_FREE(secret); VIR_FREE(secret);
} }
@ -77,6 +77,7 @@ virStorageEncryptionSecretParse(virConnectPtr conn, xmlXPathContextPtr ctxt,
virStorageEncryptionSecretPtr ret; virStorageEncryptionSecretPtr ret;
char *type_str; char *type_str;
int type; int type;
char *uuidstr = NULL;
if (VIR_ALLOC(ret) < 0) { if (VIR_ALLOC(ret) < 0) {
virReportOOMError(conn); virReportOOMError(conn);
@ -103,12 +104,25 @@ virStorageEncryptionSecretParse(virConnectPtr conn, xmlXPathContextPtr ctxt,
VIR_FREE(type_str); VIR_FREE(type_str);
ret->type = type; ret->type = type;
ret->uuid = virXPathString(conn, "string(./@uuid)", ctxt); uuidstr = virXPathString(conn, "string(./@uuid)", ctxt);
if (uuidstr) {
if (virUUIDParse(uuidstr, ret->uuid) < 0) {
virStorageReportError(conn, VIR_ERR_XML_ERROR,
_("malformed volume encryption uuid '%s'"),
uuidstr);
goto cleanup;
}
} else {
virStorageReportError(conn, VIR_ERR_XML_ERROR, "%s",
_("missing volume encryption uuid"));
goto cleanup;
}
ctxt->node = old_node; ctxt->node = old_node;
return ret; return ret;
cleanup: cleanup:
virStorageEncryptionSecretFree(ret); virStorageEncryptionSecretFree(ret);
VIR_FREE(uuidstr);
ctxt->node = old_node; ctxt->node = old_node;
return NULL; return NULL;
} }
@ -205,6 +219,7 @@ virStorageEncryptionSecretFormat(virConnectPtr conn,
virStorageEncryptionSecretPtr secret) virStorageEncryptionSecretPtr secret)
{ {
const char *type; const char *type;
char uuidstr[VIR_UUID_STRING_BUFLEN];
type = virStorageEncryptionSecretTypeTypeToString(secret->type); type = virStorageEncryptionSecretTypeTypeToString(secret->type);
if (!type) { if (!type) {
@ -213,10 +228,8 @@ virStorageEncryptionSecretFormat(virConnectPtr conn,
return -1; return -1;
} }
virBufferVSprintf(buf, " <secret type='%s'", type); virUUIDFormat(secret->uuid, uuidstr);
if (secret->uuid != NULL) virBufferVSprintf(buf, " <secret type='%s' uuid='%s'/>\n", type, uuidstr);
virBufferEscapeString(buf, " uuid='%s'", secret->uuid);
virBufferAddLit(buf, "/>\n");
return 0; return 0;
} }
@ -234,14 +247,14 @@ virStorageEncryptionFormat(virConnectPtr conn,
"%s", _("unexpected encryption format")); "%s", _("unexpected encryption format"));
return -1; return -1;
} }
virBufferVSprintf(buf, " <encryption format='%s'>\n", format); virBufferVSprintf(buf, " <encryption format='%s'>\n", format);
for (i = 0; i < enc->nsecrets; i++) { for (i = 0; i < enc->nsecrets; i++) {
if (virStorageEncryptionSecretFormat(conn, buf, enc->secrets[i]) < 0) if (virStorageEncryptionSecretFormat(conn, buf, enc->secrets[i]) < 0)
return -1; return -1;
} }
virBufferAddLit(buf, " </encryption>\n"); virBufferAddLit(buf, " </encryption>\n");
return 0; return 0;
} }

View File

@ -41,7 +41,7 @@ typedef struct _virStorageEncryptionSecret virStorageEncryptionSecret;
typedef virStorageEncryptionSecret *virStorageEncryptionSecretPtr; typedef virStorageEncryptionSecret *virStorageEncryptionSecretPtr;
struct _virStorageEncryptionSecret { struct _virStorageEncryptionSecret {
int type; /* enum virStorageEncryptionSecretType */ int type; /* enum virStorageEncryptionSecretType */
char *uuid; unsigned char uuid[VIR_UUID_BUFLEN];
}; };
enum virStorageEncryptionFormat { enum virStorageEncryptionFormat {
@ -63,6 +63,7 @@ struct _virStorageEncryption {
}; };
void virStorageEncryptionFree(virStorageEncryptionPtr enc); void virStorageEncryptionFree(virStorageEncryptionPtr enc);
virStorageEncryptionPtr virStorageEncryptionParseNode(virConnectPtr conn, virStorageEncryptionPtr virStorageEncryptionParseNode(virConnectPtr conn,
xmlDocPtr xml, xmlDocPtr xml,
xmlNodePtr root); xmlNodePtr root);

View File

@ -5270,8 +5270,9 @@ static const vshCmdOptDef opts_secret_define[] = {
static int static int
cmdSecretDefine(vshControl *ctl, const vshCmd *cmd) cmdSecretDefine(vshControl *ctl, const vshCmd *cmd)
{ {
char *from, *buffer, *uuid; char *from, *buffer;
virSecretPtr res; virSecretPtr res;
char uuid[VIR_UUID_STRING_BUFLEN];
if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
return FALSE; return FALSE;
@ -5290,15 +5291,13 @@ cmdSecretDefine(vshControl *ctl, const vshCmd *cmd)
vshError(ctl, FALSE, _("Failed to set attributes from %s"), from); vshError(ctl, FALSE, _("Failed to set attributes from %s"), from);
return FALSE; return FALSE;
} }
uuid = virSecretGetUUIDString(res); if (virSecretGetUUIDString(res, &(uuid[0])) < 0) {
if (uuid == NULL) {
vshError(ctl, FALSE, "%s", vshError(ctl, FALSE, "%s",
_("Failed to get UUID of created secret")); _("Failed to get UUID of created secret"));
virSecretFree(res); virSecretFree(res);
return FALSE; return FALSE;
} }
vshPrint(ctl, _("Secret %s created\n"), uuid); vshPrint(ctl, _("Secret %s created\n"), uuid);
free(uuid);
virSecretFree(res); virSecretFree(res);
return TRUE; return TRUE;
} }