]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: move storage encryption type to util/
authorEric Blake <eblake@redhat.com>
Fri, 28 Mar 2014 03:26:44 +0000 (21:26 -0600)
committerEric Blake <eblake@redhat.com>
Tue, 1 Apr 2014 16:38:13 +0000 (10:38 -0600)
Encryption keys can be associated with each source file in a
backing chain; as such, this file belongs more in util/ where
it can be used by virstoragefile.h.

* src/conf/storage_encryption_conf.h: Rename...
* src/util/virstorageencryption.h: ...to this.
* src/conf/storage_encryption_conf.c: Rename...
* src/util/virstorageencryption.c: ...to this.
* src/Makefile.am (ENCRYPTION_CONF_SOURCES, CONF_SOURCES)
(UTIL_SOURCES): Update to new file names.
* src/libvirt_private.syms: Likewise.
* src/conf/domain_conf.h: Update client.
* src/conf/storage_conf.h: Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
po/POTFILES.in
src/Makefile.am
src/conf/domain_conf.h
src/conf/storage_conf.h
src/conf/storage_encryption_conf.c [deleted file]
src/conf/storage_encryption_conf.h [deleted file]
src/libvirt_private.syms
src/util/virstorageencryption.c [new file with mode: 0644]
src/util/virstorageencryption.h [new file with mode: 0644]

index 5a4112a3ead90e7deecc30322ecba3e61492e119..122b85383fbe7a84077302c87f0971cb41bfd9fa 100644 (file)
@@ -28,7 +28,6 @@ src/conf/object_event.c
 src/conf/secret_conf.c
 src/conf/snapshot_conf.c
 src/conf/storage_conf.c
-src/conf/storage_encryption_conf.c
 src/conf/virchrdev.c
 src/cpu/cpu.c
 src/cpu/cpu_generic.c
@@ -193,6 +192,7 @@ src/util/virsexpr.c
 src/util/virscsi.c
 src/util/virsocketaddr.c
 src/util/virstatslinux.c
+src/util/virstorageencryption.c
 src/util/virstoragefile.c
 src/util/virstring.c
 src/util/virsysinfo.c
index 54206e4131e9a5d901fbbeea1b57a48c03cd476b..38b269758c6e86139820d1abff38c355ba20117c 100644 (file)
@@ -146,6 +146,7 @@ UTIL_SOURCES =                                                      \
                util/virsexpr.c util/virsexpr.h                 \
                util/virsocketaddr.h util/virsocketaddr.c       \
                util/virstatslinux.c util/virstatslinux.h       \
+               util/virstorageencryption.c util/virstorageencryption.h \
                util/virstoragefile.c util/virstoragefile.h     \
                util/virstring.h util/virstring.c               \
                util/virsysinfo.c util/virsysinfo.h             \
@@ -288,9 +289,6 @@ SECRET_CONF_SOURCES =                                          \
 NODE_DEVICE_CONF_SOURCES =                                     \
                conf/node_device_conf.c conf/node_device_conf.h
 
-ENCRYPTION_CONF_SOURCES =                                      \
-               conf/storage_encryption_conf.c conf/storage_encryption_conf.h
-
 CPU_CONF_SOURCES =                                             \
                conf/cpu_conf.c conf/cpu_conf.h
 
@@ -312,7 +310,6 @@ CONF_SOURCES =                                                      \
                $(NWFILTER_CONF_SOURCES)                        \
                $(NODE_DEVICE_CONF_SOURCES)                     \
                $(STORAGE_CONF_SOURCES)                         \
-               $(ENCRYPTION_CONF_SOURCES)                      \
                $(INTERFACE_CONF_SOURCES)                       \
                $(SECRET_CONF_SOURCES)                          \
                $(CPU_CONF_SOURCES)                             \
index bf92593e3adbdf9eb1e88f3aebe627502ed4bc70..b2eeefd69b7b9322c2e82323e6b9b63593f0d618 100644 (file)
@@ -30,7 +30,7 @@
 
 # include "internal.h"
 # include "capabilities.h"
-# include "storage_encryption_conf.h"
+# include "virstorageencryption.h"
 # include "cpu_conf.h"
 # include "virthread.h"
 # include "virhash.h"
index e410f414488627e7b32cc227dbd4e5e30bc1d0d5..b8110468488e36a98ff38106728fbac15734111b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * storage_conf.h: config handling for storage driver
  *
- * Copyright (C) 2006-2008, 2010-2013 Red Hat, Inc.
+ * Copyright (C) 2006-2008, 2010-2014 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -25,7 +25,7 @@
 # define __VIR_STORAGE_CONF_H__
 
 # include "internal.h"
-# include "storage_encryption_conf.h"
+# include "virstorageencryption.h"
 # include "virbitmap.h"
 # include "virthread.h"
 
diff --git a/src/conf/storage_encryption_conf.c b/src/conf/storage_encryption_conf.c
deleted file mode 100644 (file)
index bba067b..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * storage_encryption_conf.c: volume encryption information
- *
- * Copyright (C) 2009-2014 Red Hat, Inc.
- *
- * 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
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Red Hat Author: Miloslav Trmač <mitr@redhat.com>
- */
-
-#include <config.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "internal.h"
-
-#include "virbuffer.h"
-#include "viralloc.h"
-#include "storage_conf.h"
-#include "storage_encryption_conf.h"
-#include "virxml.h"
-#include "virerror.h"
-#include "viruuid.h"
-#include "virfile.h"
-
-#define VIR_FROM_THIS VIR_FROM_STORAGE
-
-VIR_ENUM_IMPL(virStorageEncryptionSecretType,
-              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);
-}
-
-static virStorageEncryptionSecretPtr
-virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
-                                xmlNodePtr node)
-{
-    xmlNodePtr old_node;
-    virStorageEncryptionSecretPtr ret;
-    char *type_str;
-    int type;
-    char *uuidstr = NULL;
-
-    if (VIR_ALLOC(ret) < 0)
-        return NULL;
-
-    old_node = ctxt->node;
-    ctxt->node = node;
-
-    type_str = virXPathString("string(./@type)", ctxt);
-    if (type_str == NULL) {
-        virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("unknown volume encryption secret type"));
-        goto cleanup;
-    }
-    type = virStorageEncryptionSecretTypeTypeFromString(type_str);
-    if (type < 0) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("unknown volume encryption secret type %s"),
-                       type_str);
-        VIR_FREE(type_str);
-        goto cleanup;
-    }
-    VIR_FREE(type_str);
-    ret->type = type;
-
-    uuidstr = virXPathString("string(./@uuid)", ctxt);
-    if (uuidstr) {
-        if (virUUIDParse(uuidstr, ret->uuid) < 0) {
-            virReportError(VIR_ERR_XML_ERROR,
-                           _("malformed volume encryption uuid '%s'"),
-                           uuidstr);
-            goto cleanup;
-        }
-        VIR_FREE(uuidstr);
-    } else {
-        virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("missing volume encryption uuid"));
-        goto cleanup;
-    }
-    ctxt->node = old_node;
-    return ret;
-
- cleanup:
-    virStorageEncryptionSecretFree(ret);
-    VIR_FREE(uuidstr);
-    ctxt->node = old_node;
-    return NULL;
-}
-
-static virStorageEncryptionPtr
-virStorageEncryptionParseXML(xmlXPathContextPtr ctxt)
-{
-    xmlNodePtr *nodes = NULL;
-    virStorageEncryptionPtr ret;
-    char *format_str;
-    int format, n;
-    size_t i;
-
-    if (VIR_ALLOC(ret) < 0)
-        return NULL;
-
-    format_str = virXPathString("string(./@format)", ctxt);
-    if (format_str == NULL) {
-        virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("unknown volume encryption format"));
-        goto cleanup;
-    }
-    format = virStorageEncryptionFormatTypeFromString(format_str);
-    if (format < 0) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("unknown volume encryption format type %s"),
-                       format_str);
-        VIR_FREE(format_str);
-        goto cleanup;
-    }
-    VIR_FREE(format_str);
-    ret->format = format;
-
-    n = virXPathNodeSet("./secret", ctxt, &nodes);
-    if (n < 0){
-        goto cleanup;
-    }
-    if (n != 0 && VIR_ALLOC_N(ret->secrets, n) < 0)
-        goto cleanup;
-    ret->nsecrets = n;
-    for (i = 0; i < n; i++) {
-        ret->secrets[i] = virStorageEncryptionSecretParse(ctxt, nodes[i]);
-        if (ret->secrets[i] == NULL)
-            goto cleanup;
-    }
-    VIR_FREE(nodes);
-
-    return ret;
-
- cleanup:
-    VIR_FREE(nodes);
-    virStorageEncryptionFree(ret);
-    return NULL;
-}
-
-virStorageEncryptionPtr
-virStorageEncryptionParseNode(xmlDocPtr xml, xmlNodePtr root)
-{
-    xmlXPathContextPtr ctxt = NULL;
-    virStorageEncryptionPtr enc = NULL;
-
-    if (STRNEQ((const char *) root->name, "encryption")) {
-        virReportError(VIR_ERR_XML_ERROR,
-                       "%s", _("unknown root element for volume "
-                               "encryption information"));
-        goto cleanup;
-    }
-
-    ctxt = xmlXPathNewContext(xml);
-    if (ctxt == NULL) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    ctxt->node = root;
-    enc = virStorageEncryptionParseXML(ctxt);
-
- cleanup:
-    xmlXPathFreeContext(ctxt);
-    return enc;
-}
-
-
-static int
-virStorageEncryptionSecretFormat(virBufferPtr buf,
-                                 virStorageEncryptionSecretPtr secret)
-{
-    const char *type;
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
-
-    type = virStorageEncryptionSecretTypeTypeToString(secret->type);
-    if (!type) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("unexpected volume encryption secret type"));
-        return -1;
-    }
-
-    virUUIDFormat(secret->uuid, uuidstr);
-    virBufferAsprintf(buf, "<secret type='%s' uuid='%s'/>\n",
-                      type, uuidstr);
-    return 0;
-}
-
-int
-virStorageEncryptionFormat(virBufferPtr buf,
-                           virStorageEncryptionPtr enc)
-{
-    const char *format;
-    size_t i;
-
-    format = virStorageEncryptionFormatTypeToString(enc->format);
-    if (!format) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("unexpected encryption format"));
-        return -1;
-    }
-    virBufferAsprintf(buf, "<encryption format='%s'>\n", format);
-    virBufferAdjustIndent(buf, 2);
-
-    for (i = 0; i < enc->nsecrets; i++) {
-        if (virStorageEncryptionSecretFormat(buf, enc->secrets[i]) < 0)
-            return -1;
-    }
-
-    virBufferAdjustIndent(buf, -2);
-    virBufferAddLit(buf, "</encryption>\n");
-
-    return 0;
-}
-
-int
-virStorageGenerateQcowPassphrase(unsigned char *dest)
-{
-    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) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Cannot open /dev/urandom"));
-        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) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("Cannot read from /dev/urandom"));
-            VIR_FORCE_CLOSE(fd);
-            return -1;
-        }
-        if (dest[i] >= 0x20 && dest[i] <= 0x7E)
-            i++; /* Got an acceptable character */
-    }
-    VIR_FORCE_CLOSE(fd);
-    return 0;
-}
diff --git a/src/conf/storage_encryption_conf.h b/src/conf/storage_encryption_conf.h
deleted file mode 100644 (file)
index 57ab1a0..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * storage_encryption_conf.h: volume encryption information
- *
- * Copyright (C) 2009-2011 Red Hat, Inc.
- *
- * 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
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Red Hat Author: Miloslav Trmač <mitr@redhat.com>
- */
-
-#ifndef __VIR_STORAGE_ENCRYPTION_H__
-# define __VIR_STORAGE_ENCRYPTION_H__
-
-# include "internal.h"
-# include "virbuffer.h"
-# include "virutil.h"
-
-# include <libxml/tree.h>
-
-enum virStorageEncryptionSecretType {
-    VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE = 0,
-
-    VIR_STORAGE_ENCRYPTION_SECRET_TYPE_LAST
-};
-VIR_ENUM_DECL(virStorageEncryptionSecretType)
-
-typedef struct _virStorageEncryptionSecret virStorageEncryptionSecret;
-typedef virStorageEncryptionSecret *virStorageEncryptionSecretPtr;
-struct _virStorageEncryptionSecret {
-    int type;                   /* enum virStorageEncryptionSecretType */
-    unsigned char uuid[VIR_UUID_BUFLEN];
-};
-
-enum virStorageEncryptionFormat {
-    /* "default" is only valid for volume creation */
-    VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT = 0,
-    VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, /* Both qcow and qcow2 */
-
-    VIR_STORAGE_ENCRYPTION_FORMAT_LAST,
-};
-VIR_ENUM_DECL(virStorageEncryptionFormat)
-
-typedef struct _virStorageEncryption virStorageEncryption;
-typedef virStorageEncryption *virStorageEncryptionPtr;
-struct _virStorageEncryption {
-    int format;            /* enum virStorageEncryptionFormat */
-
-    size_t nsecrets;
-    virStorageEncryptionSecretPtr *secrets;
-};
-
-void virStorageEncryptionFree(virStorageEncryptionPtr enc);
-
-virStorageEncryptionPtr virStorageEncryptionParseNode(xmlDocPtr xml,
-                                                      xmlNodePtr root);
-int virStorageEncryptionFormat(virBufferPtr buf,
-                               virStorageEncryptionPtr enc);
-
-/* A helper for VIR_STORAGE_ENCRYPTION_FORMAT_QCOW */
-enum {
-  VIR_STORAGE_QCOW_PASSPHRASE_SIZE = 16
-};
-
-int virStorageGenerateQcowPassphrase(unsigned char *dest);
-
-#endif /* __VIR_STORAGE_ENCRYPTION_H__ */
index 99781a241cfee37fe1921a9d03271839253d559c..60c2d447c4f7ad620efdd5946431826c04785a2e 100644 (file)
@@ -729,13 +729,6 @@ virStorageVolTypeFromString;
 virStorageVolTypeToString;
 
 
-# conf/storage_encryption_conf.h
-virStorageEncryptionFormat;
-virStorageEncryptionFree;
-virStorageEncryptionParseNode;
-virStorageGenerateQcowPassphrase;
-
-
 # conf/virchrdev.h
 virChrdevAlloc;
 virChrdevFree;
@@ -1815,6 +1808,13 @@ virSocketAddrSetIPv4Addr;
 virSocketAddrSetPort;
 
 
+# util/virstorageencryption.h
+virStorageEncryptionFormat;
+virStorageEncryptionFree;
+virStorageEncryptionParseNode;
+virStorageGenerateQcowPassphrase;
+
+
 # util/virstoragefile.h
 virStorageFileChainGetBroken;
 virStorageFileChainLookup;
diff --git a/src/util/virstorageencryption.c b/src/util/virstorageencryption.c
new file mode 100644 (file)
index 0000000..9089278
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * virstorageencryption.c: volume encryption information
+ *
+ * Copyright (C) 2009-2014 Red Hat, Inc.
+ *
+ * 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
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Red Hat Author: Miloslav Trmač <mitr@redhat.com>
+ */
+
+#include <config.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "internal.h"
+
+#include "virbuffer.h"
+#include "viralloc.h"
+#include "virstorageencryption.h"
+#include "virxml.h"
+#include "virerror.h"
+#include "viruuid.h"
+#include "virfile.h"
+
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
+VIR_ENUM_IMPL(virStorageEncryptionSecretType,
+              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);
+}
+
+static virStorageEncryptionSecretPtr
+virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
+                                xmlNodePtr node)
+{
+    xmlNodePtr old_node;
+    virStorageEncryptionSecretPtr ret;
+    char *type_str;
+    int type;
+    char *uuidstr = NULL;
+
+    if (VIR_ALLOC(ret) < 0)
+        return NULL;
+
+    old_node = ctxt->node;
+    ctxt->node = node;
+
+    type_str = virXPathString("string(./@type)", ctxt);
+    if (type_str == NULL) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("unknown volume encryption secret type"));
+        goto cleanup;
+    }
+    type = virStorageEncryptionSecretTypeTypeFromString(type_str);
+    if (type < 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unknown volume encryption secret type %s"),
+                       type_str);
+        VIR_FREE(type_str);
+        goto cleanup;
+    }
+    VIR_FREE(type_str);
+    ret->type = type;
+
+    uuidstr = virXPathString("string(./@uuid)", ctxt);
+    if (uuidstr) {
+        if (virUUIDParse(uuidstr, ret->uuid) < 0) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("malformed volume encryption uuid '%s'"),
+                           uuidstr);
+            goto cleanup;
+        }
+        VIR_FREE(uuidstr);
+    } else {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("missing volume encryption uuid"));
+        goto cleanup;
+    }
+    ctxt->node = old_node;
+    return ret;
+
+ cleanup:
+    virStorageEncryptionSecretFree(ret);
+    VIR_FREE(uuidstr);
+    ctxt->node = old_node;
+    return NULL;
+}
+
+static virStorageEncryptionPtr
+virStorageEncryptionParseXML(xmlXPathContextPtr ctxt)
+{
+    xmlNodePtr *nodes = NULL;
+    virStorageEncryptionPtr ret;
+    char *format_str;
+    int format, n;
+    size_t i;
+
+    if (VIR_ALLOC(ret) < 0)
+        return NULL;
+
+    format_str = virXPathString("string(./@format)", ctxt);
+    if (format_str == NULL) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("unknown volume encryption format"));
+        goto cleanup;
+    }
+    format = virStorageEncryptionFormatTypeFromString(format_str);
+    if (format < 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unknown volume encryption format type %s"),
+                       format_str);
+        VIR_FREE(format_str);
+        goto cleanup;
+    }
+    VIR_FREE(format_str);
+    ret->format = format;
+
+    n = virXPathNodeSet("./secret", ctxt, &nodes);
+    if (n < 0){
+        goto cleanup;
+    }
+    if (n != 0 && VIR_ALLOC_N(ret->secrets, n) < 0)
+        goto cleanup;
+    ret->nsecrets = n;
+    for (i = 0; i < n; i++) {
+        ret->secrets[i] = virStorageEncryptionSecretParse(ctxt, nodes[i]);
+        if (ret->secrets[i] == NULL)
+            goto cleanup;
+    }
+    VIR_FREE(nodes);
+
+    return ret;
+
+ cleanup:
+    VIR_FREE(nodes);
+    virStorageEncryptionFree(ret);
+    return NULL;
+}
+
+virStorageEncryptionPtr
+virStorageEncryptionParseNode(xmlDocPtr xml, xmlNodePtr root)
+{
+    xmlXPathContextPtr ctxt = NULL;
+    virStorageEncryptionPtr enc = NULL;
+
+    if (STRNEQ((const char *) root->name, "encryption")) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       "%s", _("unknown root element for volume "
+                               "encryption information"));
+        goto cleanup;
+    }
+
+    ctxt = xmlXPathNewContext(xml);
+    if (ctxt == NULL) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    ctxt->node = root;
+    enc = virStorageEncryptionParseXML(ctxt);
+
+ cleanup:
+    xmlXPathFreeContext(ctxt);
+    return enc;
+}
+
+
+static int
+virStorageEncryptionSecretFormat(virBufferPtr buf,
+                                 virStorageEncryptionSecretPtr secret)
+{
+    const char *type;
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+    type = virStorageEncryptionSecretTypeTypeToString(secret->type);
+    if (!type) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("unexpected volume encryption secret type"));
+        return -1;
+    }
+
+    virUUIDFormat(secret->uuid, uuidstr);
+    virBufferAsprintf(buf, "<secret type='%s' uuid='%s'/>\n",
+                      type, uuidstr);
+    return 0;
+}
+
+int
+virStorageEncryptionFormat(virBufferPtr buf,
+                           virStorageEncryptionPtr enc)
+{
+    const char *format;
+    size_t i;
+
+    format = virStorageEncryptionFormatTypeToString(enc->format);
+    if (!format) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "%s", _("unexpected encryption format"));
+        return -1;
+    }
+    virBufferAsprintf(buf, "<encryption format='%s'>\n", format);
+    virBufferAdjustIndent(buf, 2);
+
+    for (i = 0; i < enc->nsecrets; i++) {
+        if (virStorageEncryptionSecretFormat(buf, enc->secrets[i]) < 0)
+            return -1;
+    }
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</encryption>\n");
+
+    return 0;
+}
+
+int
+virStorageGenerateQcowPassphrase(unsigned char *dest)
+{
+    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) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot open /dev/urandom"));
+        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) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Cannot read from /dev/urandom"));
+            VIR_FORCE_CLOSE(fd);
+            return -1;
+        }
+        if (dest[i] >= 0x20 && dest[i] <= 0x7E)
+            i++; /* Got an acceptable character */
+    }
+    VIR_FORCE_CLOSE(fd);
+    return 0;
+}
diff --git a/src/util/virstorageencryption.h b/src/util/virstorageencryption.h
new file mode 100644 (file)
index 0000000..03c38a5
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * virstorageencryption.h: volume encryption information
+ *
+ * Copyright (C) 2009-2011, 2014 Red Hat, Inc.
+ *
+ * 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
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Red Hat Author: Miloslav Trmač <mitr@redhat.com>
+ */
+
+#ifndef __VIR_STORAGE_ENCRYPTION_H__
+# define __VIR_STORAGE_ENCRYPTION_H__
+
+# include "internal.h"
+# include "virbuffer.h"
+# include "virutil.h"
+
+# include <libxml/tree.h>
+
+enum virStorageEncryptionSecretType {
+    VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE = 0,
+
+    VIR_STORAGE_ENCRYPTION_SECRET_TYPE_LAST
+};
+VIR_ENUM_DECL(virStorageEncryptionSecretType)
+
+typedef struct _virStorageEncryptionSecret virStorageEncryptionSecret;
+typedef virStorageEncryptionSecret *virStorageEncryptionSecretPtr;
+struct _virStorageEncryptionSecret {
+    int type;                   /* enum virStorageEncryptionSecretType */
+    unsigned char uuid[VIR_UUID_BUFLEN];
+};
+
+enum virStorageEncryptionFormat {
+    /* "default" is only valid for volume creation */
+    VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT = 0,
+    VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, /* Both qcow and qcow2 */
+
+    VIR_STORAGE_ENCRYPTION_FORMAT_LAST,
+};
+VIR_ENUM_DECL(virStorageEncryptionFormat)
+
+typedef struct _virStorageEncryption virStorageEncryption;
+typedef virStorageEncryption *virStorageEncryptionPtr;
+struct _virStorageEncryption {
+    int format;            /* enum virStorageEncryptionFormat */
+
+    size_t nsecrets;
+    virStorageEncryptionSecretPtr *secrets;
+};
+
+void virStorageEncryptionFree(virStorageEncryptionPtr enc);
+
+virStorageEncryptionPtr virStorageEncryptionParseNode(xmlDocPtr xml,
+                                                      xmlNodePtr root);
+int virStorageEncryptionFormat(virBufferPtr buf,
+                               virStorageEncryptionPtr enc);
+
+/* A helper for VIR_STORAGE_ENCRYPTION_FORMAT_QCOW */
+enum {
+  VIR_STORAGE_QCOW_PASSPHRASE_SIZE = 16
+};
+
+int virStorageGenerateQcowPassphrase(unsigned char *dest);
+
+#endif /* __VIR_STORAGE_ENCRYPTION_H__ */