diff --git a/src/common/config.py b/src/common/config.py index c9e308a42..e46b20b10 100644 --- a/src/common/config.py +++ b/src/common/config.py @@ -314,6 +314,7 @@ class Config: 'remember_opened_chat_controls': [ opt_bool, True, _('If enabled, Gajim will reopen chat windows that were opened last time Gajim was closed.')], 'positive_184_ack': [ opt_bool, False, _('If enabled, Gajim will show an icon to show that sent message has been received by your contact')], 'show_avatar_in_tabs': [ opt_bool, False, _('Show a mini avatar in chat window tabs and in window icon')], + 'use_keyring': [opt_bool, True, _('If True, Gajim will use the Systems Keyring to store account passwords.')], }, {}) __options_per_key = { diff --git a/src/common/passwords.py b/src/common/passwords.py index 7f297b0c5..8ca769516 100644 --- a/src/common/passwords.py +++ b/src/common/passwords.py @@ -52,7 +52,7 @@ class PasswordStorage(object): class SimplePasswordStorage(PasswordStorage): def get_password(self, account_name): passwd = gajim.config.get_per('accounts', account_name, 'password') - if passwd and passwd.startswith('libsecret:'): + if passwd and (passwd.startswith('libsecret:') or passwd.startswith('winvault:')): # this is not a real password, it’s stored through libsecret. return None else: @@ -116,8 +116,14 @@ class SecretWindowsPasswordStorage(PasswordStorage): self.win_keyring = keyring.get_keyring() def save_password(self, account_name, password): - self.win_keyring.set_password('gajim', account_name, password) - gajim.config.set_per('accounts', account_name, 'password', 'winvault:') + try: + self.win_keyring.set_password('gajim', account_name, password) + gajim.config.set_per( + 'accounts', account_name, 'password', 'winvault:') + except: + log.exception('error:') + set_storage(SimplePasswordStorage()) + storage.save_password(account_name, password) def get_password(self, account_name): log.debug('getting password') @@ -127,10 +133,7 @@ class SecretWindowsPasswordStorage(PasswordStorage): if not conf.startswith('winvault:'): password = conf # migrate the password over to keyring - try: - self.save_password(account_name, password) - except Exception: - log.exception('error: ') + self.save_password(account_name, password) return password return self.win_keyring.get_password('gajim', account_name) @@ -140,19 +143,22 @@ def get_storage(): global storage if storage is None: # None is only in first time get_storage is called global Secret - try: - gi.require_version('Secret', '1') - gir = __import__('gi.repository', globals(), locals(), - ['Secret'], 0) - Secret = gir.Secret - except (ValueError, AttributeError): - pass - try: - if os.name != 'nt': - storage = SecretPasswordStorage() - else: - storage = SecretWindowsPasswordStorage() - except Exception: + if gajim.config.get('use_keyring'): + try: + gi.require_version('Secret', '1') + gir = __import__('gi.repository', globals(), locals(), + ['Secret'], 0) + Secret = gir.Secret + except (ValueError, AttributeError): + pass + try: + if os.name != 'nt': + storage = SecretPasswordStorage() + else: + storage = SecretWindowsPasswordStorage() + except Exception: + storage = SimplePasswordStorage() + else: storage = SimplePasswordStorage() return storage diff --git a/src/features_window.py b/src/features_window.py index 19ef8b3fc..23ea84897 100644 --- a/src/features_window.py +++ b/src/features_window.py @@ -69,7 +69,7 @@ class FeaturesWindow: _('Password encryption'): (self.some_keyring_available, _('Passwords can be stored securely and not just in plaintext.'), _('Requires libsecret and a provider (such as GNOME Keyring and KSecretService).'), - _('Feature not available under Windows.')), + _('On Windows the Windows Credential Vault is used.')), _('Spell Checker'): (self.speller_available, _('Spellchecking of composed messages.'), _('Requires libgtkspell.'), @@ -183,7 +183,7 @@ class FeaturesWindow: def some_keyring_available(self): if os.name == 'nt': - return False + return True try: gi.require_version('Secret', '1') from gi.repository import Secret