libxlMakeNetworkDiskSrc(virStorageSourcePtr src, char **srcstr)
{
virConnectPtr conn = NULL;
- char *secret = NULL;
+ uint8_t *secret = NULL;
+ char *base64secret = NULL;
+ size_t secretlen = 0;
char *username = NULL;
int ret = -1;
if (!(conn = virConnectOpen("xen:///system")))
goto cleanup;
- if (!(secret = virSecretGetSecretString(conn,
- true,
- src->auth,
- VIR_SECRET_USAGE_TYPE_CEPH)))
+ if (virSecretGetSecretString(conn, src->auth,
+ VIR_SECRET_USAGE_TYPE_CEPH,
+ &secret, &secretlen) < 0)
+ goto cleanup;
+
+ /* RBD expects an encoded secret */
+ if (!(base64secret = virStringEncodeBase64(secret, secretlen)))
goto cleanup;
}
- if (!(*srcstr = libxlMakeNetworkDiskSrcStr(src, username, secret)))
+ if (!(*srcstr = libxlMakeNetworkDiskSrcStr(src, username, base64secret)))
goto cleanup;
ret = 0;
cleanup:
- VIR_FREE(secret);
+ VIR_DISPOSE_N(secret, secretlen);
+ VIR_DISPOSE_STRING(base64secret);
virObjectUnref(conn);
return ret;
}
switch ((qemuDomainSecretInfoType) secinfo->type) {
case VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN:
if (secinfo->s.plain.secret) {
+ if (!virStringBufferIsPrintable(secinfo->s.plain.secret,
+ secinfo->s.plain.secretlen)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("found non printable characters in secret"));
+ return -1;
+ }
if (virAsprintf(&uri->user, "%s:%s",
secinfo->s.plain.username,
secinfo->s.plain.secret) < 0)
qemuBuildRBDSecinfoURI(virBufferPtr buf,
qemuDomainSecretInfoPtr secinfo)
{
+ char *base64secret = NULL;
+
if (!secinfo) {
virBufferAddLit(buf, ":auth_supported=none");
return 0;
switch ((qemuDomainSecretInfoType) secinfo->type) {
case VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN:
- virBufferEscape(buf, '\\', ":", ":id=%s",
- secinfo->s.plain.username);
+ if (!(base64secret = virStringEncodeBase64(secinfo->s.plain.secret,
+ secinfo->s.plain.secretlen)))
+ return -1;
+ virBufferEscape(buf, '\\', ":", ":id=%s", secinfo->s.plain.username);
virBufferEscape(buf, '\\', ":",
":key=%s:auth_supported=cephx\\;none",
- secinfo->s.plain.secret);
+ base64secret);
+ VIR_DISPOSE_STRING(base64secret);
break;
case VIR_DOMAIN_SECRET_INFO_TYPE_AES:
qemuDomainSecretPlainClear(qemuDomainSecretPlain secret)
{
VIR_FREE(secret.username);
- memset(secret.secret, 0, strlen(secret.secret));
- VIR_FREE(secret.secret);
+ VIR_DISPOSE_N(secret.secret, secret.secretlen);
}
virStorageNetProtocol protocol,
virStorageAuthDefPtr authdef)
{
- bool encode = false;
int secretType = VIR_SECRET_USAGE_TYPE_ISCSI;
secinfo->type = VIR_DOMAIN_SECRET_INFO_TYPE_PLAIN;
if (VIR_STRDUP(secinfo->s.plain.username, authdef->username) < 0)
return -1;
- if (protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
- /* qemu requires the secret to be encoded for RBD */
- encode = true;
+ if (protocol == VIR_STORAGE_NET_PROTOCOL_RBD)
secretType = VIR_SECRET_USAGE_TYPE_CEPH;
- }
-
- if (!(secinfo->s.plain.secret =
- virSecretGetSecretString(conn, encode, authdef, secretType)))
- return -1;
- return 0;
+ return virSecretGetSecretString(conn, authdef, secretType,
+ &secinfo->s.plain.secret,
+ &secinfo->s.plain.secretlen);
}
typedef struct _qemuDomainSecretPlain *qemuDomainSecretPlainPtr;
struct _qemuDomainSecretPlain {
char *username;
- char *secret;
+ uint8_t *secret;
+ size_t secretlen;
};
# define QEMU_DOMAIN_AES_IV_LEN 16 /* 16 bytes for 128 bit random */
#include "virlog.h"
#include "virobject.h"
#include "viruuid.h"
-#include "base64.h"
#include "datatypes.h"
#define VIR_FROM_THIS VIR_FROM_SECRET
/* virSecretGetSecretString:
* @conn: Pointer to the connection driver to make secret driver call
- * @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
+ * @secret: returned secret as a sized stream of unsigned chars
+ * @secret_size: Return size of the secret - either raw text or base64
*
- * Lookup the secret for the authdef usage type and return it either as
- * raw text or encoded based on the caller's need.
+ * Lookup the secret for the authdef usage type and return it as raw text.
+ * It is up to the caller to encode the secret further.
*
- * Returns a pointer to memory that needs to be cleared and free'd after
- * usage or NULL on error.
+ * Returns 0 on success, -1 on failure. On success the memory in secret
+ * needs to be cleared and free'd after usage.
*/
-char *
+int
virSecretGetSecretString(virConnectPtr conn,
- bool encoded,
virStorageAuthDefPtr authdef,
- virSecretUsageType secretUsageType)
+ virSecretUsageType secretUsageType,
+ uint8_t **secret,
+ size_t *secret_size)
{
- size_t secret_size;
virSecretPtr sec = NULL;
- char *secret = NULL;
+ int ret = -1;
switch (authdef->secretType) {
case VIR_STORAGE_SECRET_TYPE_UUID:
if (!sec)
goto cleanup;
- secret = (char *)conn->secretDriver->secretGetValue(sec, &secret_size, 0,
- VIR_SECRET_GET_VALUE_INTERNAL_CALL);
+ *secret = conn->secretDriver->secretGetValue(sec, secret_size, 0,
+ VIR_SECRET_GET_VALUE_INTERNAL_CALL);
- if (!secret)
+ if (!*secret)
goto cleanup;
- if (encoded) {
- char *base64 = NULL;
-
- base64_encode_alloc(secret, secret_size, &base64);
- VIR_FREE(secret);
- if (!base64) {
- virReportOOMError();
- goto cleanup;
- }
- secret = base64;
- }
+ ret = 0;
cleanup:
virObjectUnref(sec);
- return secret;
+ return ret;
}
# include "internal.h"
# include "virstoragefile.h"
-char *virSecretGetSecretString(virConnectPtr conn,
- bool encoded,
- virStorageAuthDefPtr authdef,
- virSecretUsageType secretUsageType)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK;
+int virSecretGetSecretString(virConnectPtr conn,
+ virStorageAuthDefPtr authdef,
+ virSecretUsageType secretUsageType,
+ uint8_t **ret_secret,
+ size_t *ret_secret_size)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4)
+ ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK;
#endif /* __VIR_SECRET_H__ */