On Thu, Aug 20, 2009 at 08:18:13PM +0200, Miloslav Trma?? wrote: > If the <encryption format='qcow'> element does not specify a secret > during volume creation, generate a suitable secret and add it to the > <encryption> tag. The caller can view the updated <encryption> tag > using virStorageVolGetXMLDesc(). > > Similarly, when <encryption format='default'/> is specified while > creating a qcow or qcow2-formatted volume, change the format to "qcow" > and generate a secret as described above. > > Changes since the third submission: > - Add "flags" parameter to virSecretDefineXML(), virSecretGetXMLDesc(), > virSecretGetValue(), virSecretSetValue(), and all derived interfaces. > --- > src/storage_backend.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++- > 1 files changed, 124 insertions(+), 3 deletions(-) > > diff --git a/src/storage_backend.c b/src/storage_backend.c > index c818142..5fa0035 100644 > --- a/src/storage_backend.c > +++ b/src/storage_backend.c > @@ -43,6 +43,7 @@ > #include <selinux/selinux.h> > #endif > > +#include "datatypes.h" > #include "virterror_internal.h" > #include "util.h" > #include "memory.h" > @@ -331,6 +332,118 @@ cleanup: > } > > static int > +virStorageGenerateQcowEncryption(virConnectPtr conn, > + virStorageVolDefPtr vol) > +{ > + virBuffer buf = VIR_BUFFER_INITIALIZER; > + virStorageEncryptionPtr enc; > + virStorageEncryptionSecretPtr enc_secret = NULL; > + virSecretPtr secret = NULL; > + char *uuid = NULL, *xml; > + unsigned char value[16]; > + int ret = -1, fd = -1; > + size_t i; > + > + if (conn->secretDriver == NULL || conn->secretDriver->defineXML == NULL || > + conn->secretDriver->setValue == NULL) { > + virStorageReportError(conn, VIR_ERR_NO_SUPPORT, "%s", > + _("secret storage not supported")); > + goto cleanup; > + } > + > + enc = vol->target.encryption; > + if (enc->nsecrets != 0) { > + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", > + _("secrets already defined")); > + goto cleanup; > + } > + > + if (VIR_ALLOC(enc_secret) < 0 || VIR_REALLOC_N(enc->secrets, 1) < 0) { > + virReportOOMError(conn); > + goto cleanup; > + } > + > + virBufferAddLit(&buf, "<secret ephemeral='no' private='no'>"); > + /* <uuid/> is chosen by the secret driver */ > + virBufferEscapeString(&buf, > + "<description>qcow passphrase for %s</description>", > + vol->target.path); > + virBufferEscapeString(&buf, "<volume>%s</volume>", vol->target.path); > + virBufferAddLit(&buf, "</secret>"); > + if (virBufferError(&buf)) { > + virReportOOMError(conn); > + goto cleanup; > + } > + xml = virBufferContentAndReset(&buf); This is the first place where we should be just calling into an internal secret_conf.h API for formatting XML from a struct, rather than duplicating the XML formatting. > + /* 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) { > + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", > + _("Cannot open /dev/urandom")); > + goto cleanup; > + } > + i = 0; > + while (i < sizeof (value)) { > + ssize_t r; > + > + while ((r = read(fd, value + i, 1)) == -1 && errno == EINTR) > + ; > + if (r <= 0) { > + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", > + _("Cannot read from /dev/urandom")); > + goto cleanup; > + } > + if (value[i] >= 0x20 && value[i] <= 0x7E) > + i++; /* Got an acceptable character */ > + } > + close(fd); I reckon this snippet of code could usefully be put into the util.h file as virFileGenerateRandomkey(), or alternatively perhaps secret_conf.h, as virSecretGenerateRandomKey(unsigned char *buf, size_t buflen); Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list