diff --git a/po/POTFILES.in b/po/POTFILES.in index 0d7f9f96ed..21d4cc6903 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -155,6 +155,7 @@ src/rpc/virnetserverservice.c src/rpc/virnetsshsession.c src/rpc/virnettlscontext.c src/secret/secret_driver.c +src/secret/secret_util.c src/security/security_apparmor.c src/security/security_dac.c src/security/security_driver.c diff --git a/src/Makefile.am b/src/Makefile.am index e63b81d26a..eda0365538 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -936,6 +936,9 @@ INTERFACE_DRIVER_SOURCES += \ endif WITH_UDEV endif WITH_INTERFACE +SECRET_UTIL_SOURCES = \ + secret/secret_util.h secret/secret_util.c + SECRET_DRIVER_SOURCES = \ secret/secret_driver.h secret/secret_driver.c @@ -1123,6 +1126,12 @@ libvirt_cpu_la_CFLAGS = \ -I$(srcdir)/conf $(AM_CFLAGS) libvirt_cpu_la_SOURCES = $(CPU_SOURCES) +noinst_LTLIBRARIES += libvirt_secret.la +libvirt_la_BUILT_LIBADD += libvirt_secret.la +libvirt_secret_la_CFLAGS = $(AM_CFLAGS) +libvirt_secret_la_LDFLAGS = $(AM_LDFLAGS) +libvirt_secret_la_SOURCES = $(SECRET_UTIL_SOURCES) + if WITH_VMX noinst_LTLIBRARIES += libvirt_vmx.la libvirt_la_BUILT_LIBADD += libvirt_vmx.la @@ -1303,10 +1312,13 @@ libvirt_driver_libxl_impl_la_CFLAGS = \ $(LIBXL_CFLAGS) \ -I$(srcdir)/access \ -I$(srcdir)/conf \ + -I$(srcdir)/secret \ -I$(srcdir)/xenconfig \ $(AM_CFLAGS) libvirt_driver_libxl_impl_la_LDFLAGS = $(AM_LDFLAGS) -libvirt_driver_libxl_impl_la_LIBADD = $(LIBXL_LIBS) libvirt_xenconfig.la +libvirt_driver_libxl_impl_la_LIBADD = $(LIBXL_LIBS) \ + libvirt_xenconfig.la \ + libvirt_secret.la libvirt_driver_libxl_impl_la_SOURCES = $(LIBXL_DRIVER_SOURCES) conf_DATA += libxl/libxl.conf @@ -1337,12 +1349,14 @@ libvirt_driver_qemu_impl_la_CFLAGS = \ $(LIBNL_CFLAGS) \ -I$(srcdir)/access \ -I$(srcdir)/conf \ + -I$(srcdir)/secret \ $(AM_CFLAGS) libvirt_driver_qemu_impl_la_LDFLAGS = $(AM_LDFLAGS) libvirt_driver_qemu_impl_la_LIBADD = $(CAPNG_LIBS) \ $(GNUTLS_LIBS) \ $(LIBNL_LIBS) \ $(LIBXML_LIBS) \ + libvirt_secret.la \ $(NULL) libvirt_driver_qemu_impl_la_SOURCES = $(QEMU_DRIVER_SOURCES) @@ -1873,6 +1887,7 @@ EXTRA_DIST += \ $(SECURITY_DRIVER_SELINUX_SOURCES) \ $(SECURITY_DRIVER_APPARMOR_SOURCES) \ $(SECRET_DRIVER_SOURCES) \ + $(SECRET_UTIL_SOURCES) \ $(VBOX_DRIVER_EXTRA_DIST) \ $(VMWARE_DRIVER_SOURCES) \ $(XENCONFIG_SOURCES) \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8bb78d9502..068bc00263 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1038,6 +1038,10 @@ nodeGetThreadsPerSubcore; nodeSetMemoryParameters; +# secret/secret_util.h +virSecretGetSecretString; + + # security/security_driver.h virSecurityDriverLookup; diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 82ba417bce..d16280da2d 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -46,7 +46,7 @@ #include "libxl_conf.h" #include "libxl_utils.h" #include "virstoragefile.h" -#include "base64.h" +#include "secret_util.h" #define VIR_FROM_THIS VIR_FROM_LIBXL @@ -935,76 +935,6 @@ libxlDomainGetEmulatorType(const virDomainDef *def) return ret; } -static char * -libxlGetSecretString(virConnectPtr conn, - const char *scheme, - bool encoded, - virStorageAuthDefPtr authdef, - virSecretUsageType secretUsageType) -{ - size_t secret_size; - virSecretPtr sec = NULL; - char *secret = NULL; - char uuidStr[VIR_UUID_STRING_BUFLEN]; - - /* look up secret */ - switch (authdef->secretType) { - case VIR_STORAGE_SECRET_TYPE_UUID: - sec = virSecretLookupByUUID(conn, authdef->secret.uuid); - virUUIDFormat(authdef->secret.uuid, uuidStr); - break; - case VIR_STORAGE_SECRET_TYPE_USAGE: - sec = virSecretLookupByUsage(conn, secretUsageType, - authdef->secret.usage); - break; - } - - if (!sec) { - if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) { - virReportError(VIR_ERR_NO_SECRET, - _("%s no secret matches uuid '%s'"), - scheme, uuidStr); - } else { - virReportError(VIR_ERR_NO_SECRET, - _("%s no secret matches usage value '%s'"), - scheme, authdef->secret.usage); - } - goto cleanup; - } - - secret = (char *)conn->secretDriver->secretGetValue(sec, &secret_size, 0, - VIR_SECRET_GET_VALUE_INTERNAL_CALL); - if (!secret) { - if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("could not get value of the secret for " - "username '%s' using uuid '%s'"), - authdef->username, uuidStr); - } else { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("could not get value of the secret for " - "username '%s' using usage value '%s'"), - authdef->username, authdef->secret.usage); - } - goto cleanup; - } - - if (encoded) { - char *base64 = NULL; - - base64_encode_alloc(secret, secret_size, &base64); - VIR_FREE(secret); - if (!base64) { - virReportOOMError(); - goto cleanup; - } - secret = base64; - } - - cleanup: - virObjectUnref(sec); - return secret; -} static char * libxlMakeNetworkDiskSrcStr(virStorageSourcePtr src, @@ -1100,11 +1030,11 @@ libxlMakeNetworkDiskSrc(virStorageSourcePtr src, char **srcstr) if (!(conn = virConnectOpen("xen:///system"))) goto cleanup; - if (!(secret = libxlGetSecretString(conn, - protocol, - true, - src->auth, - VIR_SECRET_USAGE_TYPE_CEPH))) + if (!(secret = virSecretGetSecretString(conn, + protocol, + true, + src->auth, + VIR_SECRET_USAGE_TYPE_CEPH))) goto cleanup; } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 55dec9cd1b..bd82682893 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -50,7 +50,7 @@ #include "secret_conf.h" #include "network/bridge_driver.h" #include "virnetdevtap.h" -#include "base64.h" +#include "secret_util.h" #include "device_conf.h" #include "virstoragefile.h" #include "virtpm.h" @@ -552,77 +552,6 @@ qemuSafeSerialParamValue(const char *value) return 0; } -static char * -qemuGetSecretString(virConnectPtr conn, - const char *scheme, - bool encoded, - virStorageAuthDefPtr authdef, - virSecretUsageType secretUsageType) -{ - size_t secret_size; - virSecretPtr sec = NULL; - char *secret = NULL; - char uuidStr[VIR_UUID_STRING_BUFLEN]; - - /* look up secret */ - switch (authdef->secretType) { - case VIR_STORAGE_SECRET_TYPE_UUID: - sec = virSecretLookupByUUID(conn, authdef->secret.uuid); - virUUIDFormat(authdef->secret.uuid, uuidStr); - break; - case VIR_STORAGE_SECRET_TYPE_USAGE: - sec = virSecretLookupByUsage(conn, secretUsageType, - authdef->secret.usage); - break; - } - - if (!sec) { - if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) { - virReportError(VIR_ERR_NO_SECRET, - _("%s no secret matches uuid '%s'"), - scheme, uuidStr); - } else { - virReportError(VIR_ERR_NO_SECRET, - _("%s no secret matches usage value '%s'"), - scheme, authdef->secret.usage); - } - goto cleanup; - } - - secret = (char *)conn->secretDriver->secretGetValue(sec, &secret_size, 0, - VIR_SECRET_GET_VALUE_INTERNAL_CALL); - if (!secret) { - if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("could not get value of the secret for " - "username '%s' using uuid '%s'"), - authdef->username, uuidStr); - } else { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("could not get value of the secret for " - "username '%s' using usage value '%s'"), - authdef->username, authdef->secret.usage); - } - goto cleanup; - } - - if (encoded) { - char *base64 = NULL; - - base64_encode_alloc(secret, secret_size, &base64); - VIR_FREE(secret); - if (!base64) { - virReportOOMError(); - goto cleanup; - } - secret = base64; - } - - cleanup: - virObjectUnref(sec); - return secret; -} - static int qemuNetworkDriveGetPort(int protocol, @@ -933,11 +862,11 @@ qemuGetDriveSourceString(virStorageSourcePtr src, secretType = VIR_SECRET_USAGE_TYPE_CEPH; } - if (!(secret = qemuGetSecretString(conn, - protocol, - encode, - src->auth, - secretType))) + if (!(secret = virSecretGetSecretString(conn, + protocol, + encode, + src->auth, + secretType))) goto cleanup; } } @@ -4525,8 +4454,8 @@ qemuBuildSCSIiSCSIHostdevDrvStr(virConnectPtr conn, int secretType = VIR_SECRET_USAGE_TYPE_ISCSI; username = iscsisrc->auth->username; - if (!(secret = qemuGetSecretString(conn, protocol, encode, - iscsisrc->auth, secretType))) + if (!(secret = virSecretGetSecretString(conn, protocol, encode, + iscsisrc->auth, secretType))) goto cleanup; } diff --git a/src/secret/secret_util.c b/src/secret/secret_util.c new file mode 100644 index 0000000000..217584f8c4 --- /dev/null +++ b/src/secret/secret_util.c @@ -0,0 +1,120 @@ +/* + * secret_util.c: secret related utility functions + * + * Copyright (C) 2016 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 + * . + * + */ + +#include + +#include "secret_util.h" +#include "viralloc.h" +#include "virerror.h" +#include "virlog.h" +#include "virobject.h" +#include "viruuid.h" +#include "base64.h" +#include "datatypes.h" + +#define VIR_FROM_THIS VIR_FROM_SECRET + +VIR_LOG_INIT("secret.secret_util"); + + +/* virSecretGetSecretString: + * @conn: Pointer to the connection driver to make secret driver call + * @scheme: Unique enough string for error message to help determine cause + * @encoded: Whether the returned secret needs to be base64 encoded + * @authdef: Pointer to the disk storage authentication + * @secretUsageType: Type of secret usage for authdef lookup + * + * Lookup the secret for the authdef usage type and return it either as + * raw text or encoded based on the caller's need. + * + * Returns a pointer to memory that needs to be cleared and free'd after + * usage or NULL on error. + */ +char * +virSecretGetSecretString(virConnectPtr conn, + const char *scheme, + bool encoded, + virStorageAuthDefPtr authdef, + virSecretUsageType secretUsageType) +{ + size_t secret_size; + virSecretPtr sec = NULL; + char *secret = NULL; + char uuidStr[VIR_UUID_STRING_BUFLEN]; + + /* look up secret */ + switch (authdef->secretType) { + case VIR_STORAGE_SECRET_TYPE_UUID: + sec = virSecretLookupByUUID(conn, authdef->secret.uuid); + virUUIDFormat(authdef->secret.uuid, uuidStr); + break; + case VIR_STORAGE_SECRET_TYPE_USAGE: + sec = virSecretLookupByUsage(conn, secretUsageType, + authdef->secret.usage); + break; + } + + if (!sec) { + if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) { + virReportError(VIR_ERR_NO_SECRET, + _("%s no secret matches uuid '%s'"), + scheme, uuidStr); + } else { + virReportError(VIR_ERR_NO_SECRET, + _("%s no secret matches usage value '%s'"), + scheme, authdef->secret.usage); + } + goto cleanup; + } + + secret = (char *)conn->secretDriver->secretGetValue(sec, &secret_size, 0, + VIR_SECRET_GET_VALUE_INTERNAL_CALL); + if (!secret) { + if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("could not get value of the secret for " + "username '%s' using uuid '%s'"), + authdef->username, uuidStr); + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("could not get value of the secret for " + "username '%s' using usage value '%s'"), + authdef->username, authdef->secret.usage); + } + goto cleanup; + } + + if (encoded) { + char *base64 = NULL; + + base64_encode_alloc(secret, secret_size, &base64); + VIR_FREE(secret); + if (!base64) { + virReportOOMError(); + goto cleanup; + } + secret = base64; + } + + cleanup: + virObjectUnref(sec); + return secret; +} diff --git a/src/secret/secret_util.h b/src/secret/secret_util.h new file mode 100644 index 0000000000..c707599f9a --- /dev/null +++ b/src/secret/secret_util.h @@ -0,0 +1,35 @@ +/* + * secret_util.h: secret related utility functions + * + * Copyright (C) 2016 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 + * . + * + */ + +#ifndef __VIR_SECRET_H__ +# define __VIR_SECRET_H__ + +# include "internal.h" +# include "virstoragefile.h" + +char *virSecretGetSecretString(virConnectPtr conn, + const char *scheme, + bool encoded, + virStorageAuthDefPtr authdef, + virSecretUsageType secretUsageType) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) + ATTRIBUTE_RETURN_CHECK; +#endif /* __VIR_SECRET_H__ */