mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-12-22 13:34:07 +03:00
keyring: Convert to Secrets DBUS API
This fixes keyring support since the gnome bindings are busted, while also giving us a chance of working natively on KDE. I haven't added an explicit dep on libsecret in the spec, since this is such minor functionality it's not worth pulling the dep, which should be there on all modern desktops anyways.
This commit is contained in:
parent
c60ad16b3b
commit
22c3bd62b3
1
todo.txt
1
todo.txt
@ -5,7 +5,6 @@
|
|||||||
check all XXX/TODO in the code, make sure nothing important is missing
|
check all XXX/TODO in the code, make sure nothing important is missing
|
||||||
revive import blacklist for virtinst code, maybe just a unittest that checks Gtk isn't in globals ?
|
revive import blacklist for virtinst code, maybe just a unittest that checks Gtk isn't in globals ?
|
||||||
break out osdistro bits so we don't need to carry virt-install.pod
|
break out osdistro bits so we don't need to carry virt-install.pod
|
||||||
gnome keyring entirely over dbus?
|
|
||||||
|
|
||||||
is tui working? maybe just remove it, check with mcpierce
|
is tui working? maybe just remove it, check with mcpierce
|
||||||
gsettings port (or fix gconf bindings)
|
gsettings port (or fix gconf bindings)
|
||||||
|
@ -79,17 +79,6 @@ Requires: gnome-python2-gconf >= 1.99.11-7
|
|||||||
# This version not strictly required: virt-manager should work with older,
|
# This version not strictly required: virt-manager should work with older,
|
||||||
# however varying amounts of functionality will not be enabled.
|
# however varying amounts of functionality will not be enabled.
|
||||||
Requires: libvirt-python >= 0.7.0
|
Requires: libvirt-python >= 0.7.0
|
||||||
%if 0%{?rhel} > 6
|
|
||||||
# Might work with earlier, but this is what we've tested
|
|
||||||
Requires: gnome-keyring >= 0.4.9
|
|
||||||
%else
|
|
||||||
Requires: libgnome-keyring
|
|
||||||
%endif
|
|
||||||
# Minimum we've tested with
|
|
||||||
# Although if you don't have this, comment it out and the app
|
|
||||||
# will work just fine - keyring functionality will simply be
|
|
||||||
# disabled
|
|
||||||
Requires: gnome-python2-gnomekeyring >= 2.15.4
|
|
||||||
# Minimum we've tested with
|
# Minimum we've tested with
|
||||||
Requires: libxml2-python >= 2.6.23
|
Requires: libxml2-python >= 2.6.23
|
||||||
# Earlier vte had broken python binding module
|
# Earlier vte had broken python binding module
|
||||||
|
@ -20,103 +20,98 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
try:
|
# pylint: disable=E0611
|
||||||
from gi.repository import GnomeKeyring # pylint: disable=E0611
|
from gi.repository import Gio
|
||||||
except:
|
from gi.repository import GLib
|
||||||
GnomeKeyring = None
|
# pylint: enable=E0611
|
||||||
logging.debug("GnomeKeyring bindings not installed, no keyring support")
|
|
||||||
|
|
||||||
|
|
||||||
class vmmSecret(object):
|
class vmmSecret(object):
|
||||||
def __init__(self, name, secret=None, attributes=None):
|
def __init__(self, name, secret=None, attributes=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.secret = secret
|
self.secret = secret
|
||||||
|
self.attributes = attributes
|
||||||
self.attributes = {}
|
|
||||||
if isinstance(attributes, dict):
|
|
||||||
self.attributes = attributes
|
|
||||||
elif isinstance(attributes, list):
|
|
||||||
for attr in attributes:
|
|
||||||
self.attributes[attr.name] = attr.get_string()
|
|
||||||
|
|
||||||
def get_secret(self):
|
def get_secret(self):
|
||||||
return self.secret
|
return self.secret
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def get_attributes_for_keyring(self):
|
|
||||||
attrs = GnomeKeyring.attribute_list_new()
|
|
||||||
for key, value in self.attributes.items():
|
|
||||||
GnomeKeyring.attribute_list_append_string(attrs, key, value)
|
|
||||||
return attrs
|
|
||||||
|
|
||||||
|
|
||||||
class vmmKeyring(object):
|
class vmmKeyring(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.keyring = None
|
self._collection = None
|
||||||
if GnomeKeyring is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = GnomeKeyring.get_default_keyring_sync()
|
self._dbus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
|
||||||
if result and result[0] == GnomeKeyring.Result.OK:
|
self._service = Gio.DBusProxy.new_sync(self._dbus, 0, None,
|
||||||
self.keyring = result[1]
|
"org.freedesktop.secrets",
|
||||||
|
"/org/freedesktop/secrets",
|
||||||
|
"org.freedesktop.Secret.Service", None)
|
||||||
|
|
||||||
if self.keyring is None:
|
self._session = self._service.OpenSession("(sv)", "plain",
|
||||||
self.keyring = 'default'
|
GLib.Variant("s", ""))[1]
|
||||||
logging.debug("No default keyring, creating '%s'",
|
|
||||||
self.keyring)
|
self._collection = Gio.DBusProxy.new_sync(self._dbus, 0, None,
|
||||||
try:
|
"org.freedesktop.secrets",
|
||||||
GnomeKeyring.create_sync(self.keyring, None)
|
"/org/freedesktop/secrets/aliases/default",
|
||||||
except GnomeKeyring.AlreadyExistsError:
|
"org.freedesktop.Secret.Collection", None)
|
||||||
pass
|
|
||||||
|
logging.debug("Using keyring session %s", self._session)
|
||||||
except:
|
except:
|
||||||
logging.exception("Error determining keyring")
|
logging.exception("Error determining keyring")
|
||||||
self.keyring = None
|
|
||||||
|
|
||||||
|
##############
|
||||||
|
# Public API #
|
||||||
|
##############
|
||||||
|
|
||||||
def is_available(self):
|
def is_available(self):
|
||||||
return not (self.keyring is None)
|
return not (self._collection is None)
|
||||||
|
|
||||||
def add_secret(self, secret):
|
def add_secret(self, secret):
|
||||||
_id = None
|
ret = None
|
||||||
try:
|
try:
|
||||||
result, _id = GnomeKeyring.item_create_sync(
|
props = {
|
||||||
self.keyring,
|
"org.freedesktop.Secret.Item.Label" : GLib.Variant("s", secret.get_name()),
|
||||||
GnomeKeyring.ItemType.GENERIC_SECRET,
|
"org.freedesktop.Secret.Item.Attributes" : GLib.Variant("a{ss}", secret.attributes),
|
||||||
secret.get_name(),
|
}
|
||||||
secret.get_attributes_for_keyring(),
|
params = (self._session, [],
|
||||||
secret.get_secret(),
|
[ord(v) for v in secret.get_secret()],
|
||||||
True)
|
"text/plain; charset=utf8")
|
||||||
|
replace = True
|
||||||
|
|
||||||
if result != GnomeKeyring.Result.OK:
|
_id = self._collection.CreateItem("(a{sv}(oayays)b)",
|
||||||
raise RuntimeError("Creating keyring item failed with: %s" %
|
props, params, replace)[0]
|
||||||
repr(result))
|
ret = int(_id.rsplit("/")[-1])
|
||||||
except:
|
except:
|
||||||
logging.exception("Failed to add keyring secret")
|
logging.exception("Failed to add keyring secret")
|
||||||
|
|
||||||
return _id
|
return ret
|
||||||
|
|
||||||
def get_secret(self, _id):
|
def get_secret(self, _id):
|
||||||
"""
|
ret = None
|
||||||
ignore, item = GnomeKeyring.item_get_info_sync(self.keyring, _id)
|
|
||||||
if item is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
sec = None
|
|
||||||
try:
|
try:
|
||||||
result, attrs = GnomeKeyring.item_get_attributes_sync(
|
path = self._collection.get_object_path() + "/" + str(_id)
|
||||||
self.keyring, _id)
|
iface = Gio.DBusProxy.new_sync(self._dbus, 0, None,
|
||||||
if result != GnomeKeyring.Result.OK:
|
"org.freedesktop.secrets", path,
|
||||||
raise RuntimeError("Fetching keyring attributes failed "
|
"org.freedesktop.Secret.Item", None)
|
||||||
"with %s" % result)
|
|
||||||
|
|
||||||
sec = vmmSecret(item.get_display_name(), item.get_secret(), attrs)
|
secretbytes = iface.GetSecret("(o)", self._session)[2]
|
||||||
|
label = iface.get_cached_property("Label").unpack().strip("'")
|
||||||
|
dbusattrs = iface.get_cached_property("Attributes").unpack()
|
||||||
|
|
||||||
|
secret = u"".join([unichr(c) for c in secretbytes])
|
||||||
|
|
||||||
|
attrs = {}
|
||||||
|
for key, val in dbusattrs.items():
|
||||||
|
if key not in ["hvuri", "uuid"]:
|
||||||
|
continue
|
||||||
|
attrs["%s" % key] = "%s" % val
|
||||||
|
|
||||||
|
ret = vmmSecret(label, secret, attrs)
|
||||||
except:
|
except:
|
||||||
logging.exception("Failed to lookup keyring item %s", item)
|
logging.exception("Failed to get keyring secret id=%s", _id)
|
||||||
|
|
||||||
return sec
|
return ret
|
||||||
"""
|
|
||||||
# FIXME: Uncomment this once gnome-keyring is fixed
|
|
||||||
# https://bugzilla.gnome.org/show_bug.cgi?id=691638
|
|
||||||
ignore = _id
|
|
||||||
return None
|
|
||||||
|
Loading…
Reference in New Issue
Block a user