config: Move more password handling to keyring.py

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson
2020-08-26 09:03:09 -04:00
parent ab903ef69b
commit f06cc11546
3 changed files with 85 additions and 78 deletions

View File

@ -14,7 +14,6 @@ from virtinst import DomainCpu
from virtinst import log
from .lib.inspection import vmmInspection
from .lib.keyring import vmmKeyring, vmmSecret
CSSDATA = """
@ -206,7 +205,7 @@ class vmmConfig(object):
# We don't create it straight away, since we don't want
# to block the app pending user authorization to access
# the keyring
self.keyring = None
self._keyring = None
self.default_graphics_from_config = BuildConfig.default_graphics
self.default_hvs = BuildConfig.default_hvs
@ -700,57 +699,3 @@ class vmmConfig(object):
log.debug("saving directory for type=%s to %s", key, folder)
self.conf.set("/paths/%s-default" % key, folder)
# Keyring / VNC password dealings
def get_secret_name(self, vm):
return "vm-console-" + vm.get_uuid()
def has_keyring(self):
if self.keyring is None:
self.keyring = vmmKeyring()
return self.keyring.is_available()
def get_console_password(self, vm):
if not self.has_keyring():
return ("", "")
username, keyid = vm.get_console_password()
if keyid == -1:
return ("", "")
secret = self.keyring.get_secret(keyid)
if secret is None or secret.get_name() != self.get_secret_name(vm):
return ("", "")
if (secret.attributes.get("hvuri", None) != vm.conn.get_uri() or
secret.attributes.get("uuid", None) != vm.get_uuid()):
return ("", "")
return (secret.get_secret(), username or "")
def set_console_password(self, vm, password, username=""):
if not self.has_keyring():
return
secret = vmmSecret(self.get_secret_name(vm), password,
{"uuid": vm.get_uuid(),
"hvuri": vm.conn.get_uri()})
keyid = self.keyring.add_secret(secret)
if keyid is None:
return
vm.set_console_password(username, keyid)
def del_console_password(self, vm):
if not self.has_keyring():
return
ignore, keyid = vm.get_console_password()
if keyid == -1:
return
self.keyring.del_secret(keyid)
vm.del_console_password()

View File

@ -14,6 +14,7 @@ from .serialcon import vmmSerialConsole
from .sshtunnels import ConnectionInfo
from .viewers import SpiceViewer, VNCViewer, have_spice_gtk
from ..baseclass import vmmGObject, vmmGObjectUI
from ..lib.keyring import vmmKeyring
from ..vmwindow import DETAILS_PAGE_CONSOLE
@ -608,7 +609,7 @@ class vmmConsolePages(vmmGObjectUI):
self.widget("console-unavailable").set_label("<b>" + msg + "</b>")
def _activate_auth_page(self, withPassword, withUsername):
(pw, username) = self.config.get_console_password(self.vm)
(pw, username) = vmmKeyring.get_instance().get_console_password(self.vm)
self.widget("console-auth-password").set_visible(withPassword)
self.widget("label-auth-password").set_visible(withPassword)
@ -619,11 +620,11 @@ class vmmConsolePages(vmmGObjectUI):
self.widget("console-auth-username").set_text(username)
self.widget("console-auth-password").set_text(pw)
self.widget("console-auth-remember").set_sensitive(
bool(self.config.has_keyring()))
if self.config.has_keyring():
self.widget("console-auth-remember").set_active(
bool(withPassword and pw) or (withUsername and username))
has_keyring = vmmKeyring.get_instance().is_available()
remember = bool(withPassword and pw) or (withUsername and username)
remember = has_keyring and remember
self.widget("console-auth-remember").set_sensitive(has_keyring)
self.widget("console-auth-remember").set_active(remember)
self.widget("console-pages").set_current_page(
_CONSOLE_PAGE_AUTHENTICATE)
@ -749,10 +750,10 @@ class vmmConsolePages(vmmGObjectUI):
self._viewer.console_set_username(username.get_text())
if self.widget("console-auth-remember").get_active():
self.config.set_console_password(self.vm, passwd.get_text(),
username.get_text())
vmmKeyring.get_instance().set_console_password(
self.vm, passwd.get_text(), username.get_text())
else:
self.config.del_console_password(self.vm)
vmmKeyring.get_instance().del_console_password(self.vm)
##########################

View File

@ -9,8 +9,10 @@ from gi.repository import GLib
from virtinst import log
from ..baseclass import vmmGObject
class vmmSecret(object):
class _vmmSecret(object):
def __init__(self, name, secret=None, attributes=None):
self.name = name
self.secret = secret
@ -22,9 +24,19 @@ class vmmSecret(object):
return self.name
class vmmKeyring(object):
class vmmKeyring(vmmGObject):
"""
freedesktop Secret API abstraction
"""
@classmethod
def get_instance(cls):
if not cls._instance:
cls._instance = vmmKeyring()
return cls._instance
def __init__(self):
vmmGObject.__init__(self)
self._collection = None
try:
@ -46,15 +58,10 @@ class vmmKeyring(object):
except Exception:
log.exception("Error determining keyring")
def _cleanup(self):
pass
##############
# Public API #
##############
def is_available(self):
return not (self._collection is None)
def add_secret(self, secret):
def _add_secret(self, secret):
ret = None
try:
props = {
@ -74,7 +81,7 @@ class vmmKeyring(object):
return ret
def del_secret(self, _id):
def _del_secret(self, _id):
try:
path = self._collection.get_object_path() + "/" + str(_id)
iface = Gio.DBusProxy.new_sync(self._dbus, 0, None,
@ -84,7 +91,7 @@ class vmmKeyring(object):
except Exception:
log.exception("Failed to delete keyring secret")
def get_secret(self, _id):
def _get_secret(self, _id):
ret = None
try:
path = self._collection.get_object_path() + "/" + str(_id)
@ -104,8 +111,62 @@ class vmmKeyring(object):
continue
attrs["%s" % key] = "%s" % val
ret = vmmSecret(label, secret, attrs)
ret = _vmmSecret(label, secret, attrs)
except Exception:
log.exception("Failed to get keyring secret id=%s", _id)
return ret
##############
# Public API #
##############
def is_available(self):
return not (self._collection is None)
def _get_secret_name(self, vm):
return "vm-console-" + vm.get_uuid()
def get_console_password(self, vm):
if not self.is_available():
return ("", "")
username, keyid = vm.get_console_password()
if keyid == -1:
return ("", "")
secret = self._get_secret(keyid)
if secret is None or secret.get_name() != self._get_secret_name(vm):
return ("", "")
if (secret.attributes.get("hvuri", None) != vm.conn.get_uri() or
secret.attributes.get("uuid", None) != vm.get_uuid()):
return ("", "")
return (secret.get_secret(), username or "")
def set_console_password(self, vm, password, username=""):
if not self.is_available():
return
secret = _vmmSecret(self._get_secret_name(vm), password,
{"uuid": vm.get_uuid(),
"hvuri": vm.conn.get_uri()})
keyid = self._add_secret(secret)
if keyid is None:
return
vm.set_console_password(username, keyid)
def del_console_password(self, vm):
if not self.is_available():
return
ignore, keyid = vm.get_console_password()
if keyid == -1:
return
self._del_secret(keyid)
vm.del_console_password()