On Thu, Jun 23, 2016 at 13:29:07 -0400, John Ferlan wrote:
Partially resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1301021
If the volume xml was looking to create a luks volume take the necessary
steps in order to make that happen.
The processing will be:
1. create a temporary file in the storage driver state dir path
1a. the file name will include the pool name, the volume name, secret,
and XXXXXX for usage in the mkostemp call.
1b. mkostemp the file, initially setting mode to 0600 with current
effective uid:gid as owner
1c. fetch the secret into a buffer and write that into the file
1d. change file protections to 0400
2. create a secret object
2a. use an alias combinding the volume name and "_luks0"
2b. add the file to the object
3. create/add luks options to the commandline
3a. at the very least a "key-secret" using the secret object alias
3b. if found in the XML the various "cipher" and "ivgen" options
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/storage/storage_backend.c | 260 ++++++++++++++++++++++++++++++++++++++---
src/storage/storage_backend.h | 3 +-
src/util/virqemu.c | 23 ++++
src/util/virqemu.h | 6 +
tests/storagevolxml2argvtest.c | 3 +-
6 files changed, 275 insertions(+), 21 deletions(-)
[...]
@@ -1240,6 +1366,84 @@
virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
return cmd;
}
+
+static char *
+virStorageBackendCreateQemuImgSecretPath(virConnectPtr conn,
+ virStoragePoolObjPtr pool,
+ virStorageVolDefPtr vol)
+{
+ virStorageEncryptionPtr enc = vol->target.encryption;
+ char *secretPath = NULL;
+ int fd = -1;
+ uint8_t *secret = NULL;
+ size_t secretlen = 0;
+
+ if (!enc) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing encryption description"));
+ return NULL;
+ }
+
+ if (!conn || !conn->secretDriver ||
+ !conn->secretDriver->secretLookupByUUID ||
+ !conn->secretDriver->secretLookupByUsage ||
+ !conn->secretDriver->secretGetValue) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("unable to look up encryption secret"));
+ return NULL;
+ }
+
+ /* Since we don't have a file, just go to cleanup using NULL secretPath */
+ if (!(secretPath = virStoragePoolObjBuildTempFilePath(pool, vol)))
+ goto cleanup;
+
+ if ((fd = mkostemp(secretPath, O_CLOEXEC)) < 0) {
+ virReportSystemError(errno, "%s",
+ _("failed to open luks secret file for write"));
+ goto error;
+ }
+
+ if (virSecretGetSecretString(conn, &enc->secrets[0]->seclookupdef,
+ VIR_SECRET_USAGE_TYPE_PASSPHRASE,
+ &secret, &secretlen) < 0)
+ goto error;
+
+ if (safewrite(fd, secret, secretlen) < 0) {
+ virReportSystemError(errno, "%s",
+ _("failed to write luks secret file"));
+ goto error;
+ }
+ VIR_FORCE_CLOSE(fd);
+
+ if ((vol->target.perms->uid != (uid_t) -1) &&
+ (vol->target.perms->gid != (gid_t) -1)) {
+ if (chown(secretPath, vol->target.perms->uid,
[1]
+ vol->target.perms->gid) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to chown luks secret file"));
+ goto error;
+ }
+ }
+
+ if (chmod(secretPath, 0400) < 0) {
I still don't understand this step. Owner [1] of the file is able to
add the write permission back anyways.
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to chown luks secret file"));
+ goto error;
+ }
+
+ cleanup:
+ VIR_DISPOSE_N(secret, secretlen);
+ VIR_FORCE_CLOSE(fd);
+
+ return secretPath;
+
+ error:
+ unlink(secretPath);
+ VIR_FREE(secretPath);
+ goto cleanup;
+}
+
+
int
virStorageBackendCreateQemuImg(virConnectPtr conn,
virStoragePoolObjPtr pool,
ACK with either a very good explanation or the chmod gone.