1
0
Fork 0
mirror of https://github.com/borgbase/vorta synced 2025-01-03 13:45:49 +00:00

Improve SecretStorage locking behavior. By @Aeysol (#1255)

This commit is contained in:
Aeysol 2022-04-20 06:15:08 +02:00 committed by GitHub
parent c36ac81d5e
commit 75014a756e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,6 +1,5 @@
import asyncio import asyncio
import os import os
import sys
import secretstorage import secretstorage
@ -15,30 +14,31 @@ class VortaSecretStorageKeyring(VortaKeyring):
def __init__(self): def __init__(self):
""" """
Test whether DBus and Gnome-Keyring are available. Test whether DBus and a SecretStorage provider are available.
""" """
try:
self.connection = secretstorage.dbus_init() self.connection = secretstorage.dbus_init()
except secretstorage.exceptions.SecretServiceNotAvailableException as e:
logger.debug("SecretStorage provider or DBus daemon is not available.")
raise e
asyncio.set_event_loop(asyncio.new_event_loop()) asyncio.set_event_loop(asyncio.new_event_loop())
secretstorage.get_default_collection(self.connection) self.collection = secretstorage.get_default_collection(self.connection)
def set_password(self, service, repo_url, password): def set_password(self, service, repo_url, password):
""" """
Writes a password to the underlying store. Writes a password to the underlying store.
""" """
try: if self.is_unlocked:
asyncio.set_event_loop(asyncio.new_event_loop()) asyncio.set_event_loop(asyncio.new_event_loop())
collection = secretstorage.get_default_collection(self.connection)
attributes = { attributes = {
'application': 'Vorta', 'application': 'Vorta',
'service': service, 'service': service,
'repo_url': repo_url, 'repo_url': repo_url,
'xdg:schema': 'org.freedesktop.Secret.Generic'} 'xdg:schema': 'org.freedesktop.Secret.Generic'}
collection.create_item(LABEL_TEMPLATE.format(repo_url=repo_url), self.collection.create_item(LABEL_TEMPLATE.format(repo_url=repo_url),
attributes, attributes,
password, password,
replace=True) replace=True)
except secretstorage.exceptions.ItemNotFoundException:
logger.error("SecretStorage writing failed", exc_info=sys.exc_info())
def get_password(self, service, repo_url): def get_password(self, service, repo_url):
""" """
@ -46,24 +46,20 @@ def get_password(self, service, repo_url):
""" """
if self.is_unlocked: if self.is_unlocked:
asyncio.set_event_loop(asyncio.new_event_loop()) asyncio.set_event_loop(asyncio.new_event_loop())
collection = secretstorage.get_default_collection(self.connection)
attributes = {'application': 'Vorta', 'service': service, 'repo_url': repo_url} attributes = {'application': 'Vorta', 'service': service, 'repo_url': repo_url}
items = list(collection.search_items(attributes)) items = list(self.collection.search_items(attributes))
logger.debug('Found %i passwords matching repo URL.', len(items)) logger.debug('Found %i passwords matching repo URL.', len(items))
if len(items) > 0: if len(items) > 0:
return items[0].get_secret().decode("utf-8") item = items[0]
if item.is_locked() and item.unlock():
return None
return item.get_secret().decode("utf-8")
return None return None
@property @property
def is_unlocked(self): def is_unlocked(self):
try: # unlock() will return True if the unlock prompt is dismissed
collection = secretstorage.get_default_collection(self.connection) return not (self.collection.is_locked() and self.collection.unlock())
if collection.is_locked(): # Prompt for unlock
collection.unlock()
return not collection.is_locked() # In case of denial
except secretstorage.exceptions.SecretServiceNotAvailableException:
logger.debug('SecretStorage is closed.')
return False
@classmethod @classmethod
def get_priority(cls): def get_priority(cls):