static bool cmdSecretDefine(vshControl *ctl, const vshCmd *cmd) { const char *from = NULL; char *buffer; virSecretPtr res; char uuid[VIR_UUID_STRING_BUFLEN]; bool ret = false; virshControlPtr priv = ctl->privData; if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) return false; if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) return false; if (!(res = virSecretDefineXML(priv->conn, buffer, 0))) { vshError(ctl, _("Failed to set attributes from %s"), from); goto cleanup; } if (virSecretGetUUIDString(res, &(uuid[0])) < 0) { vshError(ctl, "%s", _("Failed to get UUID of created secret")); goto cleanup; } vshPrintExtra(ctl, _("Secret %s created\n"), uuid); ret = true; cleanup: VIR_FREE(buffer); if (res) virSecretFree(res); return ret; }
static bool cmdSecretGetValue(vshControl *ctl, const vshCmd *cmd) { virSecretPtr secret; char *base64; unsigned char *value; size_t value_size; bool ret = false; secret = vshCommandOptSecret(ctl, cmd, NULL); if (secret == NULL) return false; value = virSecretGetValue(secret, &value_size, 0); if (value == NULL) goto cleanup; base64_encode_alloc((char *)value, value_size, &base64); memset(value, 0, value_size); VIR_FREE(value); if (base64 == NULL) { vshError(ctl, "%s", _("Failed to allocate memory")); goto cleanup; } vshPrint(ctl, "%s", base64); memset(base64, 0, strlen(base64)); VIR_FREE(base64); ret = true; cleanup: virSecretFree(secret); return ret; }
static bool cmdSecretGetValue(vshControl *ctl, const vshCmd *cmd) { virSecretPtr secret; VIR_AUTODISPOSE_STR base64 = NULL; unsigned char *value; size_t value_size; bool ret = false; secret = virshCommandOptSecret(ctl, cmd, NULL); if (secret == NULL) return false; value = virSecretGetValue(secret, &value_size, 0); if (value == NULL) goto cleanup; if (!(base64 = virStringEncodeBase64(value, value_size))) goto cleanup; vshPrint(ctl, "%s", base64); ret = true; cleanup: VIR_DISPOSE_N(value, value_size); virSecretFree(secret); return ret; }
/** * Update info about a volume's capacity/allocation */ static int virStorageBackendFileSystemVolRefresh(virConnectPtr conn, virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, virStorageVolDefPtr vol) { int ret; /* Refresh allocation / permissions info in case its changed */ ret = virStorageBackendUpdateVolInfo(vol, 0); if (ret < 0) return ret; /* Load any secrets if posible */ if (vol->target.encryption && vol->target.encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_QCOW && vol->target.encryption->nsecrets == 0) { virSecretPtr sec; virStorageEncryptionSecretPtr encsec = NULL; sec = virSecretLookupByUsage(conn, VIR_SECRET_USAGE_TYPE_VOLUME, vol->target.path); if (sec) { if (VIR_ALLOC_N(vol->target.encryption->secrets, 1) < 0 || VIR_ALLOC(encsec) < 0) { VIR_FREE(vol->target.encryption->secrets); virReportOOMError(); virSecretFree(sec); return -1; } vol->target.encryption->nsecrets = 1; vol->target.encryption->secrets[0] = encsec; encsec->type = VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE; virSecretGetUUID(sec, encsec->uuid); virSecretFree(sec); } } return 0; }
static void virshSecretListFree(virshSecretListPtr list) { size_t i; if (list && list->secrets) { for (i = 0; i < list->nsecrets; i++) { if (list->secrets[i]) virSecretFree(list->secrets[i]); } VIR_FREE(list->secrets); } VIR_FREE(list); }
void vert_cleanup(ErlNifEnv *env, void *obj) { VERT_RESOURCE *vp = obj; if (vp->res == NULL) return; switch (vp->type) { case VERT_RES_CONNECT: (void)virConnectClose(vp->res); break; case VERT_RES_DOMAIN: (void)virDomainFree(vp->res); break; case VERT_RES_INTERFACE: (void)virInterfaceFree(vp->res); break; case VERT_RES_NETWORK: (void)virNetworkFree(vp->res); break; case VERT_RES_NODEDEVICE: (void)virNodeDeviceFree(vp->res); break; #if HAVE_NWFILTER case VERT_RES_NWFILTER: (void)virNWFilterFree(vp->res); break; #endif case VERT_RES_SECRET: (void)virSecretFree(vp->res); break; case VERT_RES_STORAGEPOOL: (void)virStoragePoolFree(vp->res); break; case VERT_RES_STORAGEVOL: (void)virStorageVolFree(vp->res); break; case VERT_RES_STREAM: (void)virStreamFree(vp->res); break; default: break; } vp->res = NULL; }
static bool cmdSecretSetValue(vshControl *ctl, const vshCmd *cmd) { virSecretPtr secret; size_t value_size; const char *base64 = NULL; char *value; int res; bool ret = false; if (!(secret = virshCommandOptSecret(ctl, cmd, NULL))) return false; if (vshCommandOptStringReq(ctl, cmd, "base64", &base64) < 0) goto cleanup; if (!base64_decode_alloc(base64, strlen(base64), &value, &value_size)) { vshError(ctl, "%s", _("Invalid base64 data")); goto cleanup; } if (value == NULL) { vshError(ctl, "%s", _("Failed to allocate memory")); goto cleanup; } res = virSecretSetValue(secret, (unsigned char *)value, value_size, 0); memset(value, 0, value_size); VIR_FREE(value); if (res != 0) { vshError(ctl, "%s", _("Failed to set secret value")); goto cleanup; } vshPrintExtra(ctl, "%s", _("Secret value set\n")); ret = true; cleanup: virSecretFree(secret); return ret; }
static bool cmdSecretUndefine(vshControl *ctl, const vshCmd *cmd) { virSecretPtr secret; bool ret = false; const char *uuid; secret = virshCommandOptSecret(ctl, cmd, &uuid); if (secret == NULL) return false; if (virSecretUndefine(secret) < 0) { vshError(ctl, _("Failed to delete secret %s"), uuid); goto cleanup; } vshPrintExtra(ctl, _("Secret %s deleted\n"), uuid); ret = true; cleanup: virSecretFree(secret); return ret; }
static bool cmdSecretDumpXML(vshControl *ctl, const vshCmd *cmd) { virSecretPtr secret; bool ret = false; char *xml; secret = virshCommandOptSecret(ctl, cmd, NULL); if (secret == NULL) return false; xml = virSecretGetXMLDesc(secret, 0); if (xml == NULL) goto cleanup; vshPrint(ctl, "%s", xml); VIR_FREE(xml); ret = true; cleanup: virSecretFree(secret); return ret; }
static int virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr *ptr, virConnectPtr conn, virStoragePoolObjPtr pool) { int ret = -1; unsigned char *secret_value = NULL; size_t secret_value_size; char *rados_key = NULL; virBuffer mon_host = VIR_BUFFER_INITIALIZER; virSecretPtr secret = NULL; char secretUuid[VIR_UUID_STRING_BUFLEN]; int i; char *mon_buff = NULL; VIR_DEBUG("Found Cephx username: %s", pool->def->source.auth.cephx.username); if (pool->def->source.auth.cephx.username != NULL) { VIR_DEBUG("Using cephx authorization"); if (rados_create(&ptr->cluster, pool->def->source.auth.cephx.username) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to initialize RADOS")); goto cleanup; } if (pool->def->source.auth.cephx.secret.uuidUsable) { virUUIDFormat(pool->def->source.auth.cephx.secret.uuid, secretUuid); VIR_DEBUG("Looking up secret by UUID: %s", secretUuid); secret = virSecretLookupByUUIDString(conn, secretUuid); } else if (pool->def->source.auth.cephx.secret.usage != NULL) { VIR_DEBUG("Looking up secret by usage: %s", pool->def->source.auth.cephx.secret.usage); secret = virSecretLookupByUsage(conn, VIR_SECRET_USAGE_TYPE_CEPH, pool->def->source.auth.cephx.secret.usage); } if (secret == NULL) { virReportError(VIR_ERR_NO_SECRET, "%s", _("failed to find the secret")); goto cleanup; } secret_value = virSecretGetValue(secret, &secret_value_size, 0); base64_encode_alloc((char *)secret_value, secret_value_size, &rados_key); memset(secret_value, 0, secret_value_size); if (rados_key == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to decode the RADOS key")); goto cleanup; } VIR_DEBUG("Found cephx key: %s", rados_key); if (rados_conf_set(ptr->cluster, "key", rados_key) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "rados_key"); goto cleanup; } memset(rados_key, 0, strlen(rados_key)); if (rados_conf_set(ptr->cluster, "auth_supported", "cephx") < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "auth_supported"); goto cleanup; } } else { VIR_DEBUG("Not using cephx authorization"); if (rados_create(&ptr->cluster, NULL) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to create the RADOS cluster")); goto cleanup; } if (rados_conf_set(ptr->cluster, "auth_supported", "none") < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "auth_supported"); goto cleanup; } } VIR_DEBUG("Found %zu RADOS cluster monitors in the pool configuration", pool->def->source.nhost); for (i = 0; i < pool->def->source.nhost; i++) { if (pool->def->source.hosts[i].name != NULL && !pool->def->source.hosts[i].port) { virBufferAsprintf(&mon_host, "%s:6789,", pool->def->source.hosts[i].name); } else if (pool->def->source.hosts[i].name != NULL && pool->def->source.hosts[i].port) { virBufferAsprintf(&mon_host, "%s:%d,", pool->def->source.hosts[i].name, pool->def->source.hosts[i].port); } else { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("received malformed monitor, check the XML definition")); } } if (virBufferError(&mon_host)) { virReportOOMError(); goto cleanup; } mon_buff = virBufferContentAndReset(&mon_host); VIR_DEBUG("RADOS mon_host has been set to: %s", mon_buff); if (rados_conf_set(ptr->cluster, "mon_host", mon_buff) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "mon_host"); goto cleanup; } ptr->starttime = time(0); if (rados_connect(ptr->cluster) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to connect to the RADOS monitor on: %s"), mon_buff); goto cleanup; } ret = 0; cleanup: VIR_FREE(secret_value); VIR_FREE(rados_key); virSecretFree(secret); virBufferFreeAndReset(&mon_host); VIR_FREE(mon_buff); return ret; }
static int virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr, virConnectPtr conn, virStoragePoolObjPtr pool) { int ret = -1; int r = 0; unsigned char *secret_value = NULL; size_t secret_value_size; char *rados_key = NULL; virBuffer mon_host = VIR_BUFFER_INITIALIZER; virSecretPtr secret = NULL; char secretUuid[VIR_UUID_STRING_BUFLEN]; size_t i; char *mon_buff = NULL; const char *client_mount_timeout = "30"; const char *mon_op_timeout = "30"; const char *osd_op_timeout = "30"; VIR_DEBUG("Found Cephx username: %s", pool->def->source.auth.cephx.username); if (pool->def->source.auth.cephx.username != NULL) { VIR_DEBUG("Using cephx authorization"); r = rados_create(&ptr->cluster, pool->def->source.auth.cephx.username); if (r < 0) { virReportSystemError(-r, "%s", _("failed to initialize RADOS")); goto cleanup; } if (!conn) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'ceph' authentication not supported " "for autostarted pools")); return -1; } if (pool->def->source.auth.cephx.secret.uuidUsable) { virUUIDFormat(pool->def->source.auth.cephx.secret.uuid, secretUuid); VIR_DEBUG("Looking up secret by UUID: %s", secretUuid); secret = virSecretLookupByUUIDString(conn, secretUuid); } else if (pool->def->source.auth.cephx.secret.usage != NULL) { VIR_DEBUG("Looking up secret by usage: %s", pool->def->source.auth.cephx.secret.usage); secret = virSecretLookupByUsage(conn, VIR_SECRET_USAGE_TYPE_CEPH, pool->def->source.auth.cephx.secret.usage); } if (secret == NULL) { if (pool->def->source.auth.cephx.secret.uuidUsable) { virReportError(VIR_ERR_NO_SECRET, _("no secret matches uuid '%s'"), secretUuid); } else { virReportError(VIR_ERR_NO_SECRET, _("no secret matches usage value '%s'"), pool->def->source.auth.cephx.secret.usage); } goto cleanup; } secret_value = conn->secretDriver->secretGetValue(secret, &secret_value_size, 0, VIR_SECRET_GET_VALUE_INTERNAL_CALL); if (!secret_value) { if (pool->def->source.auth.cephx.secret.uuidUsable) { virReportError(VIR_ERR_INTERNAL_ERROR, _("could not get the value of the secret " "for username '%s' using uuid '%s'"), pool->def->source.auth.cephx.username, secretUuid); } else { virReportError(VIR_ERR_INTERNAL_ERROR, _("could not get the value of the secret " "for username '%s' using usage value '%s'"), pool->def->source.auth.cephx.username, pool->def->source.auth.cephx.secret.usage); } goto cleanup; } base64_encode_alloc((char *)secret_value, secret_value_size, &rados_key); memset(secret_value, 0, secret_value_size); if (rados_key == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to decode the RADOS key")); goto cleanup; } VIR_DEBUG("Found cephx key: %s", rados_key); if (rados_conf_set(ptr->cluster, "key", rados_key) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "rados_key"); goto cleanup; } memset(rados_key, 0, strlen(rados_key)); if (rados_conf_set(ptr->cluster, "auth_supported", "cephx") < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "auth_supported"); goto cleanup; } } else { VIR_DEBUG("Not using cephx authorization"); if (rados_create(&ptr->cluster, NULL) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to create the RADOS cluster")); goto cleanup; } if (rados_conf_set(ptr->cluster, "auth_supported", "none") < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "auth_supported"); goto cleanup; } } VIR_DEBUG("Found %zu RADOS cluster monitors in the pool configuration", pool->def->source.nhost); for (i = 0; i < pool->def->source.nhost; i++) { if (pool->def->source.hosts[i].name != NULL && !pool->def->source.hosts[i].port) { virBufferAsprintf(&mon_host, "%s:6789,", pool->def->source.hosts[i].name); } else if (pool->def->source.hosts[i].name != NULL && pool->def->source.hosts[i].port) { virBufferAsprintf(&mon_host, "%s:%d,", pool->def->source.hosts[i].name, pool->def->source.hosts[i].port); } else { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("received malformed monitor, check the XML definition")); } } if (virBufferError(&mon_host)) { virReportOOMError(); goto cleanup; } mon_buff = virBufferContentAndReset(&mon_host); VIR_DEBUG("RADOS mon_host has been set to: %s", mon_buff); if (rados_conf_set(ptr->cluster, "mon_host", mon_buff) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set RADOS option: %s"), "mon_host"); goto cleanup; } /* * Set timeout options for librados. * In case the Ceph cluster is down libvirt won't block forever. * Operations in librados will return -ETIMEDOUT when the timeout is reached. */ VIR_DEBUG("Setting RADOS option client_mount_timeout to %s", client_mount_timeout); rados_conf_set(ptr->cluster, "client_mount_timeout", client_mount_timeout); VIR_DEBUG("Setting RADOS option rados_mon_op_timeout to %s", mon_op_timeout); rados_conf_set(ptr->cluster, "rados_mon_op_timeout", mon_op_timeout); VIR_DEBUG("Setting RADOS option rados_osd_op_timeout to %s", osd_op_timeout); rados_conf_set(ptr->cluster, "rados_osd_op_timeout", osd_op_timeout); ptr->starttime = time(0); r = rados_connect(ptr->cluster); if (r < 0) { virReportSystemError(-r, _("failed to connect to the RADOS monitor on: %s"), mon_buff); goto cleanup; } ret = 0; cleanup: VIR_FREE(secret_value); VIR_FREE(rados_key); if (secret != NULL) virSecretFree(secret); virBufferFreeAndReset(&mon_host); VIR_FREE(mon_buff); return ret; }