6ae9ed
From 47fc4f22b1ebc54f3ffb6f36f8efb7f9304ef1c5 Mon Sep 17 00:00:00 2001
6ae9ed
Message-Id: <47fc4f22b1ebc54f3ffb6f36f8efb7f9304ef1c5@dist-git>
6ae9ed
From: John Ferlan <jferlan@redhat.com>
6ae9ed
Date: Mon, 25 Jul 2016 12:42:46 -0400
6ae9ed
Subject: [PATCH] util: Add 'usage' for encryption
6ae9ed
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1301021
6ae9ed
6ae9ed
In order to use more common code and set up for a future type, modify the
6ae9ed
encryption secret to allow the "usage" attribute or the "uuid" attribute
6ae9ed
to define the secret. The "usage" in the case of a volume secret would be
6ae9ed
the path to the volume as dictated by the backwards compatibility brought
6ae9ed
on by virStorageGenerateQcowEncryption where it set up the usage field as
6ae9ed
the vol->target.path and didn't allow someone to provide it. This carries
6ae9ed
into virSecretObjListFindByUsageLocked which takes the secret usage attribute
6ae9ed
value from from the domain disk definition and compares it against the
6ae9ed
usage type from the secret definition. Since none of the code dealing
6ae9ed
with qcow/qcow2 encryption secrets uses usage for lookup, it's a mostly
6ae9ed
cosmetic change. The real usage comes in a future path where the encryption
6ae9ed
is expanded to be a luks volume and the secret will allow definition of
6ae9ed
the usage field.
6ae9ed
6ae9ed
This code will make use of the virSecretLookup{Parse|Format}Secret common code.
6ae9ed
6ae9ed
Signed-off-by: John Ferlan <jferlan@redhat.com>
6ae9ed
(cherry picked from commit 47e88b33befa1aafa4fd4db99c77a45c66d41c0a)
6ae9ed
---
6ae9ed
 docs/formatstorageencryption.html.in               | 12 +++++---
6ae9ed
 docs/schemas/storagecommon.rng                     | 11 +++++--
6ae9ed
 src/qemu/qemu_process.c                            | 13 +++-----
6ae9ed
 src/storage/storage_backend.c                      |  3 +-
6ae9ed
 src/storage/storage_backend_fs.c                   |  3 +-
6ae9ed
 src/util/virstorageencryption.c                    | 26 ++++++----------
6ae9ed
 src/util/virstorageencryption.h                    |  3 +-
6ae9ed
 .../qemuxml2argv-encrypted-disk-usage.args         | 24 +++++++++++++++
6ae9ed
 .../qemuxml2argv-encrypted-disk-usage.xml          | 36 ++++++++++++++++++++++
6ae9ed
 tests/qemuxml2argvtest.c                           |  1 +
6ae9ed
 .../qemuxml2xmlout-encrypted-disk-usage.xml        |  1 +
6ae9ed
 tests/qemuxml2xmltest.c                            |  1 +
6ae9ed
 12 files changed, 98 insertions(+), 36 deletions(-)
6ae9ed
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk-usage.args
6ae9ed
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk-usage.xml
6ae9ed
 create mode 120000 tests/qemuxml2xmloutdata/qemuxml2xmlout-encrypted-disk-usage.xml
6ae9ed
6ae9ed
diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in
6ae9ed
index 04c3346..58e1073 100644
6ae9ed
--- a/docs/formatstorageencryption.html.in
6ae9ed
+++ b/docs/formatstorageencryption.html.in
6ae9ed
@@ -25,10 +25,14 @@
6ae9ed
     

6ae9ed
       The encryption tag can currently contain a sequence of
6ae9ed
       secret tags, each with mandatory attributes type
6ae9ed
-      and uuid.  The only currently defined value of
6ae9ed
-      type is passphrase.  uuid
6ae9ed
-      refers to a secret known to libvirt.  libvirt can use a secret value
6ae9ed
-      previously set using virSecretSetValue(), or, if supported
6ae9ed
+      and either uuid or usage
6ae9ed
+      (since 2.1.0). The only currently defined
6ae9ed
+      value of type is passphrase. The
6ae9ed
+      uuid is "uuid" of the secret while
6ae9ed
+      usage is the value "usage" subelement field.
6ae9ed
+      A secret value can be set in libvirt by the
6ae9ed
+      
6ae9ed
+      virSecretSetValue API. Alternatively, if supported
6ae9ed
       by the particular volume format and driver, automatically generate a
6ae9ed
       secret value at the time of volume creation, and store it using the
6ae9ed
       specified uuid.
6ae9ed
diff --git a/docs/schemas/storagecommon.rng b/docs/schemas/storagecommon.rng
6ae9ed
index 7c04462..c5b71de 100644
6ae9ed
--- a/docs/schemas/storagecommon.rng
6ae9ed
+++ b/docs/schemas/storagecommon.rng
6ae9ed
@@ -27,9 +27,14 @@
6ae9ed
           <value>passphrase</value>
6ae9ed
         </choice>
6ae9ed
       </attribute>
6ae9ed
-      <attribute name='uuid'>
6ae9ed
-        <ref name="UUID"/>
6ae9ed
-      </attribute>
6ae9ed
+      <choice>
6ae9ed
+        <attribute name='uuid'>
6ae9ed
+          <ref name="UUID"/>
6ae9ed
+        </attribute>
6ae9ed
+        <attribute name='usage'>
6ae9ed
+          <text/>
6ae9ed
+        </attribute>
6ae9ed
+      </choice>
6ae9ed
     </element>
6ae9ed
   </define>
6ae9ed
 
6ae9ed
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
6ae9ed
index 4eb35ea..4ffd9b7 100644
6ae9ed
--- a/src/qemu/qemu_process.c
6ae9ed
+++ b/src/qemu/qemu_process.c
6ae9ed
@@ -70,6 +70,7 @@
6ae9ed
 #include "virnuma.h"
6ae9ed
 #include "virstring.h"
6ae9ed
 #include "virhostdev.h"
6ae9ed
+#include "secret_util.h"
6ae9ed
 #include "storage/storage_driver.h"
6ae9ed
 #include "configmake.h"
6ae9ed
 #include "nwfilter_conf.h"
6ae9ed
@@ -377,7 +378,6 @@ qemuProcessGetVolumeQcowPassphrase(virConnectPtr conn,
6ae9ed
                                    char **secretRet,
6ae9ed
                                    size_t *secretLen)
6ae9ed
 {
6ae9ed
-    virSecretPtr secret;
6ae9ed
     char *passphrase;
6ae9ed
     unsigned char *data;
6ae9ed
     size_t size;
6ae9ed
@@ -416,14 +416,9 @@ qemuProcessGetVolumeQcowPassphrase(virConnectPtr conn,
6ae9ed
         goto cleanup;
6ae9ed
     }
6ae9ed
 
6ae9ed
-    secret = conn->secretDriver->secretLookupByUUID(conn,
6ae9ed
-                                                    enc->secrets[0]->uuid);
6ae9ed
-    if (secret == NULL)
6ae9ed
-        goto cleanup;
6ae9ed
-    data = conn->secretDriver->secretGetValue(secret, &size, 0,
6ae9ed
-                                              VIR_SECRET_GET_VALUE_INTERNAL_CALL);
6ae9ed
-    virObjectUnref(secret);
6ae9ed
-    if (data == NULL)
6ae9ed
+    if (virSecretGetSecretString(conn, &enc->secrets[0]->seclookupdef,
6ae9ed
+                                 VIR_SECRET_USAGE_TYPE_VOLUME,
6ae9ed
+                                 &data, &size) < 0)
6ae9ed
         goto cleanup;
6ae9ed
 
6ae9ed
     if (memchr(data, '\0', size) != NULL) {
6ae9ed
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
6ae9ed
index 5adf1fd..d6a451d 100644
6ae9ed
--- a/src/storage/storage_backend.c
6ae9ed
+++ b/src/storage/storage_backend.c
6ae9ed
@@ -648,7 +648,8 @@ virStorageGenerateQcowEncryption(virConnectPtr conn,
6ae9ed
         goto cleanup;
6ae9ed
 
6ae9ed
     enc_secret->type = VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE;
6ae9ed
-    memcpy(enc_secret->uuid, secret->uuid, VIR_UUID_BUFLEN);
6ae9ed
+    enc_secret->seclookupdef.type = VIR_SECRET_LOOKUP_TYPE_UUID;
6ae9ed
+    memcpy(enc_secret->seclookupdef.u.uuid, secret->uuid, VIR_UUID_BUFLEN);
6ae9ed
     enc->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
6ae9ed
     enc->secrets[0] = enc_secret; /* Space for secrets[0] allocated above */
6ae9ed
     enc_secret = NULL;
6ae9ed
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
6ae9ed
index 44dabf4..839a2c7 100644
6ae9ed
--- a/src/storage/storage_backend_fs.c
6ae9ed
+++ b/src/storage/storage_backend_fs.c
6ae9ed
@@ -1312,7 +1312,8 @@ virStorageBackendFileSystemLoadDefaultSecrets(virConnectPtr conn,
6ae9ed
     vol->target.encryption->secrets[0] = encsec;
6ae9ed
 
6ae9ed
     encsec->type = VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE;
6ae9ed
-    virSecretGetUUID(sec, encsec->uuid);
6ae9ed
+    encsec->seclookupdef.type = VIR_SECRET_LOOKUP_TYPE_UUID;
6ae9ed
+    virSecretGetUUID(sec, encsec->seclookupdef.u.uuid);
6ae9ed
     virObjectUnref(sec);
6ae9ed
 
6ae9ed
     return 0;
6ae9ed
diff --git a/src/util/virstorageencryption.c b/src/util/virstorageencryption.c
6ae9ed
index 8105158..afb44da 100644
6ae9ed
--- a/src/util/virstorageencryption.c
6ae9ed
+++ b/src/util/virstorageencryption.c
6ae9ed
@@ -34,6 +34,7 @@
6ae9ed
 #include "virerror.h"
6ae9ed
 #include "viruuid.h"
6ae9ed
 #include "virfile.h"
6ae9ed
+#include "virsecret.h"
6ae9ed
 
6ae9ed
 #define VIR_FROM_THIS VIR_FROM_STORAGE
6ae9ed
 
6ae9ed
@@ -114,6 +115,7 @@ virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
6ae9ed
     virStorageEncryptionSecretPtr ret;
6ae9ed
     char *type_str = NULL;
6ae9ed
     char *uuidstr = NULL;
6ae9ed
+    char *usagestr = NULL;
6ae9ed
 
6ae9ed
     if (VIR_ALLOC(ret) < 0)
6ae9ed
         return NULL;
6ae9ed
@@ -133,21 +135,12 @@ virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
6ae9ed
                        type_str);
6ae9ed
         goto cleanup;
6ae9ed
     }
6ae9ed
+
6ae9ed
+    if (virSecretLookupParseSecret(node, &ret->seclookupdef) < 0)
6ae9ed
+        goto cleanup;
6ae9ed
+
6ae9ed
     VIR_FREE(type_str);
6ae9ed
 
6ae9ed
-    if ((uuidstr = virXPathString("string(./@uuid)", ctxt))) {
6ae9ed
-        if (virUUIDParse(uuidstr, ret->uuid) < 0) {
6ae9ed
-            virReportError(VIR_ERR_XML_ERROR,
6ae9ed
-                           _("malformed volume encryption uuid '%s'"),
6ae9ed
-                           uuidstr);
6ae9ed
-            goto cleanup;
6ae9ed
-        }
6ae9ed
-        VIR_FREE(uuidstr);
6ae9ed
-    } else {
6ae9ed
-        virReportError(VIR_ERR_XML_ERROR, "%s",
6ae9ed
-                       _("missing volume encryption uuid"));
6ae9ed
-        goto cleanup;
6ae9ed
-    }
6ae9ed
     ctxt->node = old_node;
6ae9ed
     return ret;
6ae9ed
 
6ae9ed
@@ -155,6 +148,7 @@ virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
6ae9ed
     VIR_FREE(type_str);
6ae9ed
     virStorageEncryptionSecretFree(ret);
6ae9ed
     VIR_FREE(uuidstr);
6ae9ed
+    VIR_FREE(usagestr);
6ae9ed
     ctxt->node = old_node;
6ae9ed
     return NULL;
6ae9ed
 }
6ae9ed
@@ -244,7 +238,6 @@ virStorageEncryptionSecretFormat(virBufferPtr buf,
6ae9ed
                                  virStorageEncryptionSecretPtr secret)
6ae9ed
 {
6ae9ed
     const char *type;
6ae9ed
-    char uuidstr[VIR_UUID_STRING_BUFLEN];
6ae9ed
 
6ae9ed
     if (!(type = virStorageEncryptionSecretTypeToString(secret->type))) {
6ae9ed
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6ae9ed
@@ -252,9 +245,8 @@ virStorageEncryptionSecretFormat(virBufferPtr buf,
6ae9ed
         return -1;
6ae9ed
     }
6ae9ed
 
6ae9ed
-    virUUIDFormat(secret->uuid, uuidstr);
6ae9ed
-    virBufferAsprintf(buf, "<secret type='%s' uuid='%s'/>\n",
6ae9ed
-                      type, uuidstr);
6ae9ed
+    virSecretLookupFormatSecret(buf, type, &secret->seclookupdef);
6ae9ed
+
6ae9ed
     return 0;
6ae9ed
 }
6ae9ed
 
6ae9ed
diff --git a/src/util/virstorageencryption.h b/src/util/virstorageencryption.h
6ae9ed
index 04641b1..c68c66e 100644
6ae9ed
--- a/src/util/virstorageencryption.h
6ae9ed
+++ b/src/util/virstorageencryption.h
6ae9ed
@@ -25,6 +25,7 @@
6ae9ed
 
6ae9ed
 # include "internal.h"
6ae9ed
 # include "virbuffer.h"
6ae9ed
+# include "virsecret.h"
6ae9ed
 # include "virutil.h"
6ae9ed
 
6ae9ed
 # include <libxml/tree.h>
6ae9ed
@@ -40,7 +41,7 @@ typedef struct _virStorageEncryptionSecret virStorageEncryptionSecret;
6ae9ed
 typedef virStorageEncryptionSecret *virStorageEncryptionSecretPtr;
6ae9ed
 struct _virStorageEncryptionSecret {
6ae9ed
     int type; /* virStorageEncryptionSecretType */
6ae9ed
-    unsigned char uuid[VIR_UUID_BUFLEN];
6ae9ed
+    virSecretLookupTypeDef seclookupdef;
6ae9ed
 };
6ae9ed
 
6ae9ed
 typedef enum {
6ae9ed
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk-usage.args b/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk-usage.args
6ae9ed
new file mode 100644
6ae9ed
index 0000000..4371413
6ae9ed
--- /dev/null
6ae9ed
+++ b/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk-usage.args
6ae9ed
@@ -0,0 +1,24 @@
6ae9ed
+LC_ALL=C \
6ae9ed
+PATH=/bin \
6ae9ed
+HOME=/home/test \
6ae9ed
+USER=test \
6ae9ed
+LOGNAME=test \
6ae9ed
+QEMU_AUDIO_DRV=none \
6ae9ed
+/usr/bin/qemu \
6ae9ed
+-name encryptdisk \
6ae9ed
+-S \
6ae9ed
+-M pc \
6ae9ed
+-m 1024 \
6ae9ed
+-smp 1 \
6ae9ed
+-uuid 496898a6-e6ff-f7c8-5dc2-3cf410945ee9 \
6ae9ed
+-nographic \
6ae9ed
+-nodefaults \
6ae9ed
+-monitor unix:/tmp/lib/domain--1-encryptdisk/monitor.sock,server,nowait \
6ae9ed
+-no-acpi \
6ae9ed
+-boot c \
6ae9ed
+-usb \
6ae9ed
+-drive file=/storage/guest_disks/encryptdisk,format=qcow2,if=none,\
6ae9ed
+id=drive-virtio-disk0 \
6ae9ed
+-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
6ae9ed
+id=virtio-disk0 \
6ae9ed
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
6ae9ed
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk-usage.xml b/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk-usage.xml
6ae9ed
new file mode 100644
6ae9ed
index 0000000..ec6413f
6ae9ed
--- /dev/null
6ae9ed
+++ b/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk-usage.xml
6ae9ed
@@ -0,0 +1,36 @@
6ae9ed
+<domain type='qemu'>
6ae9ed
+  <name>encryptdisk</name>
6ae9ed
+  <uuid>496898a6-e6ff-f7c8-5dc2-3cf410945ee9</uuid>
6ae9ed
+  <memory unit='KiB'>1048576</memory>
6ae9ed
+  <currentMemory unit='KiB'>524288</currentMemory>
6ae9ed
+  <vcpu placement='static'>1</vcpu>
6ae9ed
+  <os>
6ae9ed
+    <type arch='i686' machine='pc'>hvm</type>
6ae9ed
+    <boot dev='hd'/>
6ae9ed
+  </os>
6ae9ed
+  <clock offset='utc'/>
6ae9ed
+  <on_poweroff>destroy</on_poweroff>
6ae9ed
+  <on_reboot>restart</on_reboot>
6ae9ed
+  <on_crash>destroy</on_crash>
6ae9ed
+  <devices>
6ae9ed
+    <emulator>/usr/bin/qemu</emulator>
6ae9ed
+    <disk type='file' device='disk'>
6ae9ed
+      <driver name='qemu' type='qcow2'/>
6ae9ed
+      <source file='/storage/guest_disks/encryptdisk'/>
6ae9ed
+      <target dev='vda' bus='virtio'/>
6ae9ed
+      <encryption format='qcow'>
6ae9ed
+        <secret type='passphrase' usage='/storage/guest_disks/encryptdisk'/>
6ae9ed
+      </encryption>
6ae9ed
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
6ae9ed
+    </disk>
6ae9ed
+    <controller type='usb' index='0'>
6ae9ed
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
6ae9ed
+    </controller>
6ae9ed
+    <controller type='pci' index='0' model='pci-root'/>
6ae9ed
+    <input type='mouse' bus='ps2'/>
6ae9ed
+    <input type='keyboard' bus='ps2'/>
6ae9ed
+    <memballoon model='virtio'>
6ae9ed
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
6ae9ed
+    </memballoon>
6ae9ed
+  </devices>
6ae9ed
+</domain>
6ae9ed
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
6ae9ed
index 7fc10a8..d37d125 100644
6ae9ed
--- a/tests/qemuxml2argvtest.c
6ae9ed
+++ b/tests/qemuxml2argvtest.c
6ae9ed
@@ -1361,6 +1361,7 @@ mymain(void)
6ae9ed
     driver.caps->host.cpu = cpuDefault;
6ae9ed
 
6ae9ed
     DO_TEST("encrypted-disk", NONE);
6ae9ed
+    DO_TEST("encrypted-disk-usage", NONE);
6ae9ed
 
6ae9ed
     DO_TEST("memtune", NONE);
6ae9ed
     DO_TEST("memtune-unlimited", NONE);
6ae9ed
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-encrypted-disk-usage.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-encrypted-disk-usage.xml
6ae9ed
new file mode 120000
6ae9ed
index 0000000..824120a
6ae9ed
--- /dev/null
6ae9ed
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-encrypted-disk-usage.xml
6ae9ed
@@ -0,0 +1 @@
6ae9ed
+../qemuxml2argvdata/qemuxml2argv-encrypted-disk-usage.xml
6ae9ed
\ No newline at end of file
6ae9ed
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
6ae9ed
index 2112d39..693e712 100644
6ae9ed
--- a/tests/qemuxml2xmltest.c
6ae9ed
+++ b/tests/qemuxml2xmltest.c
6ae9ed
@@ -501,6 +501,7 @@ mymain(void)
6ae9ed
     DO_TEST("pci-serial-dev-chardev");
6ae9ed
 
6ae9ed
     DO_TEST("encrypted-disk");
6ae9ed
+    DO_TEST("encrypted-disk-usage");
6ae9ed
     DO_TEST("memtune");
6ae9ed
     DO_TEST("memtune-unlimited");
6ae9ed
     DO_TEST("blkiotune");
6ae9ed
-- 
6ae9ed
2.9.2
6ae9ed