diff --git a/todo.txt b/todo.txt index 627676feb..bed160103 100644 --- a/todo.txt +++ b/todo.txt @@ -5,7 +5,6 @@ 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 ? 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 gsettings port (or fix gconf bindings) diff --git a/virt-manager.spec b/virt-manager.spec index 7d0c012b0..aad8f3669 100644 --- a/virt-manager.spec +++ b/virt-manager.spec @@ -79,17 +79,6 @@ Requires: gnome-python2-gconf >= 1.99.11-7 # This version not strictly required: virt-manager should work with older, # however varying amounts of functionality will not be enabled. 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 Requires: libxml2-python >= 2.6.23 # Earlier vte had broken python binding module diff --git a/virtManager/keyring.py b/virtManager/keyring.py index 008aee35f..b178f7f34 100644 --- a/virtManager/keyring.py +++ b/virtManager/keyring.py @@ -20,103 +20,98 @@ import logging -try: - from gi.repository import GnomeKeyring # pylint: disable=E0611 -except: - GnomeKeyring = None - logging.debug("GnomeKeyring bindings not installed, no keyring support") +# pylint: disable=E0611 +from gi.repository import Gio +from gi.repository import GLib +# pylint: enable=E0611 class vmmSecret(object): def __init__(self, name, secret=None, attributes=None): self.name = name self.secret = secret - - self.attributes = {} - if isinstance(attributes, dict): - self.attributes = attributes - elif isinstance(attributes, list): - for attr in attributes: - self.attributes[attr.name] = attr.get_string() + self.attributes = attributes def get_secret(self): return self.secret def get_name(self): 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): + def __init__(self): - self.keyring = None - if GnomeKeyring is None: - return + self._collection = None try: - result = GnomeKeyring.get_default_keyring_sync() - if result and result[0] == GnomeKeyring.Result.OK: - self.keyring = result[1] + self._dbus = Gio.bus_get_sync(Gio.BusType.SESSION, None) + self._service = Gio.DBusProxy.new_sync(self._dbus, 0, None, + "org.freedesktop.secrets", + "/org/freedesktop/secrets", + "org.freedesktop.Secret.Service", None) - if self.keyring is None: - self.keyring = 'default' - logging.debug("No default keyring, creating '%s'", - self.keyring) - try: - GnomeKeyring.create_sync(self.keyring, None) - except GnomeKeyring.AlreadyExistsError: - pass + self._session = self._service.OpenSession("(sv)", "plain", + GLib.Variant("s", ""))[1] + + self._collection = Gio.DBusProxy.new_sync(self._dbus, 0, None, + "org.freedesktop.secrets", + "/org/freedesktop/secrets/aliases/default", + "org.freedesktop.Secret.Collection", None) + + logging.debug("Using keyring session %s", self._session) except: logging.exception("Error determining keyring") - self.keyring = None + + + ############## + # Public API # + ############## def is_available(self): - return not (self.keyring is None) + return not (self._collection is None) def add_secret(self, secret): - _id = None + ret = None try: - result, _id = GnomeKeyring.item_create_sync( - self.keyring, - GnomeKeyring.ItemType.GENERIC_SECRET, - secret.get_name(), - secret.get_attributes_for_keyring(), - secret.get_secret(), - True) + props = { + "org.freedesktop.Secret.Item.Label" : GLib.Variant("s", secret.get_name()), + "org.freedesktop.Secret.Item.Attributes" : GLib.Variant("a{ss}", secret.attributes), + } + params = (self._session, [], + [ord(v) for v in secret.get_secret()], + "text/plain; charset=utf8") + replace = True - if result != GnomeKeyring.Result.OK: - raise RuntimeError("Creating keyring item failed with: %s" % - repr(result)) + _id = self._collection.CreateItem("(a{sv}(oayays)b)", + props, params, replace)[0] + ret = int(_id.rsplit("/")[-1]) except: logging.exception("Failed to add keyring secret") - return _id + return ret def get_secret(self, _id): - """ - ignore, item = GnomeKeyring.item_get_info_sync(self.keyring, _id) - if item is None: - return - - sec = None + ret = None try: - result, attrs = GnomeKeyring.item_get_attributes_sync( - self.keyring, _id) - if result != GnomeKeyring.Result.OK: - raise RuntimeError("Fetching keyring attributes failed " - "with %s" % result) + path = self._collection.get_object_path() + "/" + str(_id) + iface = Gio.DBusProxy.new_sync(self._dbus, 0, None, + "org.freedesktop.secrets", path, + "org.freedesktop.Secret.Item", None) - 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: - logging.exception("Failed to lookup keyring item %s", item) + logging.exception("Failed to get keyring secret id=%s", _id) - return sec - """ - # FIXME: Uncomment this once gnome-keyring is fixed - # https://bugzilla.gnome.org/show_bug.cgi?id=691638 - ignore = _id - return None + return ret