Define an <encryption> tag specifying volume encryption format and format-depenedent parameters (e.g. passphrase, cipher name, key length, key). Currently the only defined parameter is a reference to a "secret" (passphrase/key) managed using the virSecret* API. Only the qcow/qcow2 encryption format, and a "default" format used to let libvirt choose the format during volume creation, is currently supported. This patch does not add any users; the <encryption> tag is added in the following patches to both volumes (to support encrypted volume creation) and domains. Changes since the second submission; - Remove <optional> from the <encryption> schema - Drop <encryption format='unencrypted'/> - s/secret_id/uuid/g - Fix indentation --- bootstrap | 1 + docs/format.html | 4 + docs/formatcaps.html | 4 + docs/formatdomain.html | 4 + docs/formatnetwork.html | 4 + docs/formatnode.html | 4 + docs/formatsecret.html | 4 + docs/formatstorage.html | 4 + docs/formatstorageencryption.html | 209 +++++++++++++++++++++++++++++ docs/formatstorageencryption.html.in | 65 +++++++++ docs/schemas/Makefile.am | 1 + docs/schemas/storageencryption.rng | 34 +++++ docs/sitemap.html | 3 + docs/sitemap.html.in | 4 + po/POTFILES.in | 1 + src/Makefile.am | 1 + src/libvirt_private.syms | 5 + src/storage_encryption.c | 241 ++++++++++++++++++++++++++++++++++ src/storage_encryption.h | 72 ++++++++++ 19 files changed, 665 insertions(+), 0 deletions(-) create mode 100644 docs/formatstorageencryption.html create mode 100644 docs/formatstorageencryption.html.in create mode 100644 docs/schemas/storageencryption.rng create mode 100644 src/storage_encryption.c create mode 100644 src/storage_encryption.h diff --git a/bootstrap b/bootstrap index 8b81e0e..885b299 100755 --- a/bootstrap +++ b/bootstrap @@ -65,6 +65,7 @@ gnulib_tool=$GNULIB_SRCDIR/gnulib-tool <$gnulib_tool || exit modules=' +base64 c-ctype close connect diff --git a/docs/format.html b/docs/format.html index 3c20b5f..e8b1498 100644 --- a/docs/format.html +++ b/docs/format.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatcaps.html b/docs/formatcaps.html index 5f2bc72..3240101 100644 --- a/docs/formatcaps.html +++ b/docs/formatcaps.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <span class="active">Capabilities</span> </div> </li><li> diff --git a/docs/formatdomain.html b/docs/formatdomain.html index 6b655ad..efba65a 100644 --- a/docs/formatdomain.html +++ b/docs/formatdomain.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatnetwork.html b/docs/formatnetwork.html index 72a3cda..845e558 100644 --- a/docs/formatnetwork.html +++ b/docs/formatnetwork.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatnode.html b/docs/formatnode.html index 516c27b..b269baa 100644 --- a/docs/formatnode.html +++ b/docs/formatnode.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatsecret.html b/docs/formatsecret.html index 998e874..929eb86 100644 --- a/docs/formatsecret.html +++ b/docs/formatsecret.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatstorage.html b/docs/formatstorage.html index 02cbcac..8c16a0f 100644 --- a/docs/formatstorage.html +++ b/docs/formatstorage.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatstorageencryption.html b/docs/formatstorageencryption.html new file mode 100644 index 0000000..15175fe --- /dev/null +++ b/docs/formatstorageencryption.html @@ -0,0 +1,209 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- + This file is autogenerated from formatstorageencryption.html.in + Do not edit this file. Changes will be lost. + --> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> + <link rel="stylesheet" type="text/css" href="main.css" /> + <link rel="SHORTCUT ICON" href="32favicon.png" /> + <title>libvirt: Storage volume encryption XML format</title> + <meta name="description" content="libvirt, virtualization, virtualization API" /> + </head> + <body> + <div id="header"> + <div id="headerLogo"></div> + <div id="headerSearch"> + <form action="search.php" enctype="application/x-www-form-urlencoded" method="get"><div> + <input id="query" name="query" type="text" size="12" value="" /> + <input id="submit" name="submit" type="submit" value="Search" /> + </div></form> + </div> + </div> + <div id="body"> + <div id="menu"> + <ul class="l0"><li> + <div> + <a title="Front page of the libvirt website" class="inactive" href="index.html">Home</a> + </div> + </li><li> + <div> + <a title="Details of new features and bugs fixed in each release" class="inactive" href="news.html">News</a> + </div> + </li><li> + <div> + <a title="Get the latest source releases, binary builds and get access to the source repository" class="inactive" href="downloads.html">Downloads</a> + </div> + </li><li> + <div> + <a title="Information for users, administrators and developers" class="active" href="docs.html">Documentation</a> + <ul class="l1"><li> + <div> + <a title="Information about deploying and using libvirt" class="inactive" href="deployment.html">Deployment</a> + </div> + </li><li> + <div> + <a title="Overview of the logical subsystems in the libvirt API" class="inactive" href="intro.html">Architecture</a> + </div> + </li><li> + <div> + <a title="Description of the XML formats used in libvirt" class="active" href="format.html">XML format</a> + <ul class="l2"><li> + <div> + <a title="The domain XML format" class="inactive" href="formatdomain.html">Domains</a> + </div> + </li><li> + <div> + <a title="The virtual network XML format" class="inactive" href="formatnetwork.html">Networks</a> + </div> + </li><li> + <div> + <a title="The storage pool and volume XML format" class="inactive" href="formatstorage.html">Storage</a> + </div> + </li><li> + <div> + <span class="active">Storage Encryption</span> + </div> + </li><li> + <div> + <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> + </div> + </li><li> + <div> + <a title="The host device XML format" class="inactive" href="formatnode.html">Node Devices</a> + </div> + </li><li> + <div> + <a title="The secret XML format" class="inactive" href="formatsecret.html">Secrets</a> + </div> + </li></ul> + </div> + </li><li> + <div> + <a title="Hypervisor specific driver information" class="inactive" href="drivers.html">Drivers</a> + </div> + </li><li> + <div> + <a title="Reference manual for the C public API" class="inactive" href="html/index.html">API reference</a> + </div> + </li><li> + <div> + <a title="Bindings of the libvirt API for other languages" class="inactive" href="bindings.html">Language bindings</a> + </div> + </li><li> + <div> + <a title="Working on the internals of libvirt API, driver and daemon code" class="inactive" href="internals.html">Internals</a> + </div> + </li></ul> + </div> + </li><li> + <div> + <a title="User contributed content" class="inactive" href="http://wiki.libvirt.org">Wiki</a> + </div> + </li><li> + <div> + <a title="Frequently asked questions" class="inactive" href="FAQ.html">FAQ</a> + </div> + </li><li> + <div> + <a title="How and where to report bugs and request features" class="inactive" href="bugs.html">Bug reports</a> + </div> + </li><li> + <div> + <a title="How to contact the developers via email and IRC" class="inactive" href="contact.html">Contact</a> + </div> + </li><li> + <div> + <a title="Miscellaneous links of interest related to libvirt" class="inactive" href="relatedlinks.html">Related Links</a> + </div> + </li><li> + <div> + <a title="Overview of all content on the website" class="inactive" href="sitemap.html">Sitemap</a> + </div> + </li></ul> + </div> + <div id="content"> + <h1>Storage volume encryption XML format</h1> + <ul><li> + <a href="#StorageEncryption">Storage volume encryption XML</a> + <ul><li> + <a href="#StorageEncryptionDefault">"default" format</a> + </li><li> + <a href="#StorageEncryptionQcow">"qcow" format</a> + </li></ul> + </li><li> + <a href="#example">Example</a> + </li></ul> + <h2> + <a name="StorageEncryption" id="StorageEncryption">Storage volume encryption XML</a> + </h2> + <p> + Storage volumes may be encrypted, the XML snippet described below is used + to represent the details of the encryption. It can be used as a part + of a domain or storage configuration. + </p> + <p> + The top-level tag of volume encryption specification + is <code>encryption</code>, with a mandatory + attribute <code>format</code>. Currently defined values + of <code>format</code> are <code>default</code> and <code>qcow</code>. + Each value of <code>format</code> implies some expectations about the + content of the <code>encryption</code> tag. Other format values may be + defined in the future. + </p> + <p> + The <code>encryption</code> tag can currently contain a sequence of + <code>secret</code> tags, each with mandatory attributes <code>type</code> + and <code>uuid</code>. The only currently defined value of + <code>type</code> is <code>passphrase</code>. <code>uuid</code> + refers to a secret known to libvirt. libvirt can use a secret value + previously set using <code>virSecretSetValue()</code>, or, if supported + by the particular volume format and driver, automatically generate a + secret value at the time of volume creation, and store it using the + specified <code>uuid</code>. + </p> + <p> + </p> + <h3> + <a name="StorageEncryptionDefault" id="StorageEncryptionDefault">"default" format</a> + </h3> + <p> + <code><encryption type="default"/></code> can be specified only + when creating a volume. If the volume is successfully created, the + encryption formats, parameters and secrets will be auto-generated by + libvirt and the attached <code>encryption</code> tag will be updated. + The unmodified contents of the <code>encryption</code> tag can be used + in later operations with the volume, or when setting up a domain that + uses the volume. + </p> + <h3> + <a name="StorageEncryptionQcow" id="StorageEncryptionQcow">"qcow" format</a> + </h3> + <p> + The <code>qcow</code> format specifies that the built-in encryption + support in <code>qcow</code>- or <code>qcow2</code>-formatted volume + images should be used. A single + <code><secret type='passphrase'></code> element is expected. If + the <code>secret</code> element is not present during volume creation, + a secret is automatically generated and attached to the volume. + </p> + <h2> + <a name="example" id="example">Example</a> + </h2> + <p> + Here is a simple example, specifying use of the <code>qcow</code> format: + </p> + <pre> + <encryption format='qcow'> + <secret type='passphrase' uuid='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' /> + </encryption></pre> + </div> + </div> + <div id="footer"> + <p id="sponsor"> + Sponsored by:<br /><a href="http://et.redhat.com/"><img src="et.png" alt="Project sponsored by Red Hat Emerging Technology" /></a></p> + </div> + </body> +</html> diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in new file mode 100644 index 0000000..0e5dcee --- /dev/null +++ b/docs/formatstorageencryption.html.in @@ -0,0 +1,65 @@ +<html> + <body> + <h1>Storage volume encryption XML format</h1> + + <ul id="toc"></ul> + + <h2><a name="StorageEncryption">Storage volume encryption XML</a></h2> + + <p> + Storage volumes may be encrypted, the XML snippet described below is used + to represent the details of the encryption. It can be used as a part + of a domain or storage configuration. + </p> + <p> + The top-level tag of volume encryption specification + is <code>encryption</code>, with a mandatory + attribute <code>format</code>. Currently defined values + of <code>format</code> are <code>default</code> and <code>qcow</code>. + Each value of <code>format</code> implies some expectations about the + content of the <code>encryption</code> tag. Other format values may be + defined in the future. + </p> + <p> + The <code>encryption</code> tag can currently contain a sequence of + <code>secret</code> tags, each with mandatory attributes <code>type</code> + and <code>uuid</code>. The only currently defined value of + <code>type</code> is <code>passphrase</code>. <code>uuid</code> + refers to a secret known to libvirt. libvirt can use a secret value + previously set using <code>virSecretSetValue()</code>, or, if supported + by the particular volume format and driver, automatically generate a + secret value at the time of volume creation, and store it using the + specified <code>uuid</code>. + <p> + <h3><a name="StorageEncryptionDefault">"default" format</a></h3> + <p> + <code><encryption type="default"/></code> can be specified only + when creating a volume. If the volume is successfully created, the + encryption formats, parameters and secrets will be auto-generated by + libvirt and the attached <code>encryption</code> tag will be updated. + The unmodified contents of the <code>encryption</code> tag can be used + in later operations with the volume, or when setting up a domain that + uses the volume. + </p> + <h3><a name="StorageEncryptionQcow">"qcow" format</a></h3> + <p> + The <code>qcow</code> format specifies that the built-in encryption + support in <code>qcow</code>- or <code>qcow2</code>-formatted volume + images should be used. A single + <code><secret type='passphrase'></code> element is expected. If + the <code>secret</code> element is not present during volume creation, + a secret is automatically generated and attached to the volume. + </p> + + <h2><a name="example">Example</a></h2> + + <p> + Here is a simple example, specifying use of the <code>qcow</code> format: + </p> + + <pre> + <encryption format='qcow'> + <secret type='passphrase' uuid='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' /> + </encryption></pre> + </body> +</html> diff --git a/docs/schemas/Makefile.am b/docs/schemas/Makefile.am index a064518..c217d69 100644 --- a/docs/schemas/Makefile.am +++ b/docs/schemas/Makefile.am @@ -6,6 +6,7 @@ schema_DATA = \ interface.rng \ network.rng \ secret.rng \ + storageencryption.rng \ storagepool.rng \ storagevol.rng \ nodedev.rng \ diff --git a/docs/schemas/storageencryption.rng b/docs/schemas/storageencryption.rng new file mode 100644 index 0000000..8f9cd62 --- /dev/null +++ b/docs/schemas/storageencryption.rng @@ -0,0 +1,34 @@ +<!-- A Relax NG schema for the libvirt volume encryption XML format --> +<grammar xmlns="http://relaxng.org/ns/structure/1.0" + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + + <define name='encryption'> + <element name='encryption'> + <attribute name='format'> + <choice> + <value>default</value> + <value>qcow</value> + </choice> + </attribute> + <zeroOrMore> + <ref name='secret'/> + </zeroOrMore> + </element> + </define> + + <define name='secret'> + <element name='secret'> + <attribute name='type'> + <choice> + <value>passphrase</value> + </choice> + </attribute> + <optional> + <attribute name='uuid'> + <text/> + </attribute> + </optional> + </element> + </define> + +</grammar> diff --git a/docs/sitemap.html b/docs/sitemap.html index 901633d..24300d5 100644 --- a/docs/sitemap.html +++ b/docs/sitemap.html @@ -136,6 +136,9 @@ <a href="formatstorage.html">Storage</a> <span>The storage pool and volume XML format</span> </li><li> + <a href="formatstorageencryption.html">Storage Encryption</a> + <span>Storage volume encryption XML format</span> + </li><li> <a href="formatcaps.html">Capabilities</a> <span>The driver capabilities XML format</span> </li><li> diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in index 2ed25c6..65de169 100644 --- a/docs/sitemap.html.in +++ b/docs/sitemap.html.in @@ -99,6 +99,10 @@ <span>The storage pool and volume XML format</span> </li> <li> + <a href="formatstorageencryption.html">Storage Encryption</a> + <span>Storage volume encryption XML format</span> + </li> + <li> <a href="formatcaps.html">Capabilities</a> <span>The driver capabilities XML format</span> </li> diff --git a/po/POTFILES.in b/po/POTFILES.in index e9d388a..ac3b2d6 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -41,6 +41,7 @@ src/storage_backend_logical.c src/storage_backend_scsi.c src/storage_conf.c src/storage_driver.c +src/storage_encryption.c src/test.c src/uml_conf.c src/uml_driver.c diff --git a/src/Makefile.am b/src/Makefile.am index ce33695..2c1c9b4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -52,6 +52,7 @@ UTIL_SOURCES = \ memory.c memory.h \ pci.c pci.h \ qparams.c qparams.h \ + storage_encryption.h storage_encryption.c \ threads.c threads.h \ threads-pthread.h \ threads-win32.h \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index dd691be..c86e213 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -342,6 +342,11 @@ virStoragePartedFsTypeTypeToString; virStoragePoolObjLock; virStoragePoolObjUnlock; +virStorageEncryptionFree; +virStorageEncryptionDropSecrets; +virStorageEncryptionParseNode; +virStorageEncryptionFormat; + # threads.h virMutexInit; diff --git a/src/storage_encryption.c b/src/storage_encryption.c new file mode 100644 index 0000000..ccb29ed --- /dev/null +++ b/src/storage_encryption.c @@ -0,0 +1,241 @@ +/* + * storage_encryption.h: volume encryption information + * + * Copyright (C) 2009 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Red Hat Author: Miloslav TrmaÄ? <mitr@xxxxxxxxxx> + */ + +#include <config.h> + +#include "internal.h" + +#include "base64.h" +#include "buf.h" +#include "memory.h" +#include "storage_conf.h" +#include "storage_encryption.h" +#include "util.h" +#include "xml.h" +#include "virterror_internal.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->uuid); + 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(virConnectPtr conn, xmlXPathContextPtr ctxt, + xmlNodePtr node) +{ + xmlNodePtr old_node; + virStorageEncryptionSecretPtr ret; + char *type_str; + int type; + + if (VIR_ALLOC(ret) < 0) { + virReportOOMError(conn); + return NULL; + } + + old_node = ctxt->node; + ctxt->node = node; + + type_str = virXPathString(conn, "string(./@type)", ctxt); + if (type_str == NULL) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, "%s", + _("unknown volume encryption secret type")); + goto cleanup; + } + type = virStorageEncryptionSecretTypeTypeFromString(type_str); + if (type < 0) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, + _("unknown volume encryption secret type %s"), + type_str); + VIR_FREE(type_str); + goto cleanup; + } + VIR_FREE(type_str); + ret->type = type; + + ret->uuid = virXPathString(conn, "string(./@uuid)", ctxt); + ctxt->node = old_node; + return ret; + + cleanup: + virStorageEncryptionSecretFree(ret); + ctxt->node = old_node; + return NULL; +} + +static virStorageEncryptionPtr +virStorageEncryptionParseXML(virConnectPtr conn, xmlXPathContextPtr ctxt) +{ + xmlNodePtr *nodes = NULL; + virStorageEncryptionPtr ret; + char *format_str; + int format, i, n; + + if (VIR_ALLOC(ret) < 0) { + virReportOOMError(conn); + return NULL; + } + + format_str = virXPathString(conn, "string(./@format)", ctxt); + if (format_str == NULL) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, "%s", + _("unknown volume encryption format")); + goto cleanup; + } + format = virStorageEncryptionFormatTypeFromString(format_str); + if (format < 0) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, + _("unknown volume encryption format type %s"), + format_str); + VIR_FREE(format_str); + goto cleanup; + } + VIR_FREE(format_str); + ret->format = format; + + n = virXPathNodeSet(conn, "./secret", ctxt, &nodes); + if (n < 0){ + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot extract volume encryption secrets")); + goto cleanup; + } + if (n != 0 && VIR_ALLOC_N(ret->secrets, n) < 0) { + virReportOOMError(conn); + goto cleanup; + } + ret->nsecrets = n; + for (i = 0; i < n; i++) { + ret->secrets[i] = virStorageEncryptionSecretParse(conn, 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(virConnectPtr conn, + xmlDocPtr xml, xmlNodePtr root) +{ + xmlXPathContextPtr ctxt = NULL; + virStorageEncryptionPtr enc = NULL; + + if (STRNEQ((const char *) root->name, "encryption")) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, + "%s", _("unknown root element for volume " + "encryption information")); + goto cleanup; + } + + ctxt = xmlXPathNewContext(xml); + if (ctxt == NULL) { + virReportOOMError(conn); + goto cleanup; + } + + ctxt->node = root; + enc = virStorageEncryptionParseXML(conn, ctxt); + + cleanup: + xmlXPathFreeContext(ctxt); + return enc; +} + +static int +virStorageEncryptionSecretFormat(virConnectPtr conn, + virBufferPtr buf, + virStorageEncryptionSecretPtr secret) +{ + const char *type; + + type = virStorageEncryptionSecretTypeTypeToString(secret->type); + if (!type) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("unexpected volume encryption secret type")); + return -1; + } + + virBufferVSprintf(buf, " <secret type='%s'", type); + if (secret->uuid != NULL) + virBufferEscapeString(buf, " uuid='%s'", secret->uuid); + virBufferAddLit(buf, "/>\n"); + return 0; +} + +int +virStorageEncryptionFormat(virConnectPtr conn, + virBufferPtr buf, + virStorageEncryptionPtr enc) +{ + const char *format; + size_t i; + + format = virStorageEncryptionFormatTypeToString(enc->format); + if (!format) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("unexpected encryption format")); + return -1; + } + virBufferVSprintf(buf, " <encryption format='%s'>\n", format); + + for (i = 0; i < enc->nsecrets; i++) { + if (virStorageEncryptionSecretFormat(conn, buf, enc->secrets[i]) < 0) + return -1; + } + + virBufferAddLit(buf, " </encryption>\n"); + + return 0; +} diff --git a/src/storage_encryption.h b/src/storage_encryption.h new file mode 100644 index 0000000..0e377cb --- /dev/null +++ b/src/storage_encryption.h @@ -0,0 +1,72 @@ +/* + * storage_encryption.h: volume encryption information + * + * Copyright (C) 2009 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Red Hat Author: Miloslav TrmaÄ? <mitr@xxxxxxxxxx> + */ + +#ifndef __VIR_STORAGE_ENCRYPTION_H__ +#define __VIR_STORAGE_ENCRYPTION_H__ + +#include "internal.h" +#include "buf.h" +#include "util.h" + +#include <stdbool.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 */ + char *uuid; +}; + +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(virConnectPtr conn, + xmlDocPtr xml, + xmlNodePtr root); +int virStorageEncryptionFormat(virConnectPtr conn, virBufferPtr buf, + virStorageEncryptionPtr enc); + +#endif /* __VIR_STORAGE_ENCRYPTION_H__ */ -- 1.6.2.5 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list