Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backintime-qt: Fails to access password with new keyring package (ChainerBackend not supported) #1410

Closed
aryoda opened this issue Feb 24, 2023 · 11 comments
Assignees
Labels
Bug High Keyrings uses a keyring like kdewallet, SecretService, GnomeKeyring Reproduced
Milestone

Comments

@aryoda
Copy link
Contributor

aryoda commented Feb 24, 2023

Overview

A bug report at Debian (many thanks to Sven Geuer) and also others here (see tag Keyrings) showed that
the new ChainerBackend of the keyring package is now the default backend and it is not supported in BiT
(which white-lists the supported keyring backends).

Symptoms

Logging output (DEBUG log level):

No appropriate keyring found. 'keyring.backends.chainer' can't be used with BackInTime

For details see also this FR #1330 which explains the backgrounds.

Proposed fix

I propose to fix this bug ASAP by enabling ChainerBackend support in BiT.
I had already documented and prepared this fix three months ago:

backintime/common/tools.py

Lines 889 to 897 in e22c7f2

# TODO (Oct. 7, 2022): Should the ChainerBackend also be supported?
# It could solve the problem of configuring the
# used backend since it iterates over all of them
# and seems to be the default backend now.
# On the other hand it could use a non-supported
# backend without a chance for BiT to notice this.
# See: https://github.com/jaraco/keyring/blob/977ed03677bb0602b91f005461ef3dddf01a49f6/keyring/backends/chainer.py#L11
# try: backends.append(keyring.backends.chainer.ChainerBackend)
# except Exception as e: logger.debug("Metaclass keyring.backend. not found:" + repr(e))

Chainer will loop over all installed keyring backends (password safes) and tries to find the requested password:

https://github.com/jaraco/keyring/blob/7ffff5b285d6f9d9b8cba33a9d5e9071cdd507b9/keyring/backends/chainer.py#L47-L51

Possibly unwanted side-effect: Setting a password uses the highest-ranked password safe (if more than one is installed) so updating a password may leave the old password in a lower-ranked password safe untouched and create a new entry in another higher-ranked password safe. This "change in password-safe ranking" may e.g. occur if another password safe is installed...

https://github.com/jaraco/keyring/blob/7ffff5b285d6f9d9b8cba33a9d5e9071cdd507b9/keyring/backends/chainer.py#L53-L58

Alternatives

  • Probe the supported backends for already stored BiT credentials and choose the matching backend automatically
    (if only one: How to cope with password in different password safes if BiT does only pick one?)

  • BiT could update an existing password in the same backend where the old password exists
    (may not be the same backend chosen by ChainerBackend!)

@aryoda aryoda added High Bug Keyrings uses a keyring like kdewallet, SecretService, GnomeKeyring labels Feb 24, 2023
@aryoda aryoda self-assigned this Feb 24, 2023
@68420948
Copy link

Thanks for logging this so prominently here. I support the proposed fix.

In regards to Debian we are a bit in a hurry as Bookworm, the upcoming stable release, will enter the hard freeze phase on March, 12th which means the fix should have been applied in Debian before this date.

Regards, Sven

@Fantu
Copy link
Contributor

Fantu commented Feb 25, 2023

fixes can be applied as debian/patches with new upload also after the hard freeze (if maintainer will accept them), packages with autopkgtests have migration of 20 days and other will need request unblock to release team, and after full freeze need request unblock all.
What is more difficult is propose stable update after the release, that is only for RC bugs (and some important bugs) and is more "difficult", excluding the security fixes that is faster and near always done by security team.
Anyway first the fixes is better be applied upstream and tested enough to avoid regression.

@aryoda
Copy link
Contributor Author

aryoda commented Mar 3, 2023

@Fantu I have now prepared and tested the fix to support the chainer backend in my PR #1413.

Could you please have a look at my changes (not much code changed, but more comments ;-)
and give me advice on how to proceed to keep the Debian freeze date (March 12, 2023?).

We could prepare a new release or the changes could be applied via a patch from the diff:

https://github.com/bit-team/backintime/pull/1413/files#diff-aefcaf4a21864b54ca4e7ccb0febb72a9400694db77381e505cc23433f1bb729

@68420948
Copy link

68420948 commented Mar 4, 2023

@aryoda, I built a Debian package containing your patch in my local environment though tests unfortunately failed.

Test Result Details

ChainerBackend is recognized as supported now and a password is reportedly available while unlocking the SSH private key fails. Even after having stored the password anew (via the GUI) a restarted instance of BiT fails to unlock the SSH private key. A GUI dialog says

Could not unlock ssh private key. Wrong password or password not available for cron.

Debug output says

$ LANG=C backintime-qt --debug
DEBUG: [common/backintime.py:589 argParse] Arguments: {'debug': True} | unknownArgs: []

Back In Time
Version: 1.3.3

Back In Time comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; type `backintime --license' for details.

DEBUG: [common/backintime.py:677 getConfig] config file: /home/sg/.config/backintime/config
DEBUG: [common/backintime.py:678 getConfig] share path: /home/sg/.local/share/backintime
DEBUG: [common/backintime.py:679 getConfig] profiles: 1=Main profile
DEBUG: [common/pluginmanager.py:240 PluginManager.load] Register plugin path /usr/share/backintime/plugins
DEBUG: [common/pluginmanager.py:257 PluginManager.load] Add plugin qt4plugin.py
DEBUG: [common/pluginmanager.py:257 PluginManager.load] Add plugin notifyplugin.py
QSocketNotifier: Can only be used with threads started with QThread
DEBUG: [qt/qttools.py:175 createQApplication] QT QPA platform plugin: wayland
DEBUG: [qt/qttools.py:176 createQApplication] QT_QPA_PLATFORMTHEME=gnome
DEBUG: [qt/qttools.py:178 createQApplication] QT_STYLE_OVERRIDE=<not set>
DEBUG: [qt/qttools.py:179 createQApplication] QT active style: fusion
DEBUG: [qt/qttools.py:180 createQApplication] QT fallback style: Adwaita
DEBUG: [qt/qttools.py:181 createQApplication] QT supported styles: ['Windows', 'Fusion']
DEBUG: [qt/qttools.py:182 createQApplication] themeSearchPaths: ['/usr/share/icons', ':/icons']
DEBUG: [qt/qttools.py:183 createQApplication] fallbackSearchPaths: []
DEBUG: [qt/qttools.py:185 createQApplication] Is SystemTray available: False
DEBUG: [qt/qttools.py:197 createQApplication] Trying to set App ID for non-privileged user
DEBUG: [common/tools.py:859 keyringSupported] Keyring config file folder: /home/sg/.config/python_keyring
DEBUG: [common/tools.py:873 keyringSupported] Available keyring backends:
DEBUG: [common/tools.py:876 keyringSupported] keyring.backends.fail.Keyring (priority: 0)
DEBUG: [common/tools.py:876 keyringSupported] keyring.backends.SecretService.Keyring (priority: 5)
DEBUG: [common/tools.py:876 keyringSupported] keyring.backends.libsecret.Keyring (priority: 4.8)
DEBUG: [common/tools.py:876 keyringSupported] keyring.backends.chainer.ChainerBackend (priority: 10)
DEBUG: [common/tools.py:889 keyringSupported] Metaclass keyring.backends.Gnome.Keyring not found: AttributeError("module 'keyring.backends' has no attribute 'Gnome'")
DEBUG: [common/tools.py:891 keyringSupported] Metaclass keyring.backends.kwallet.Keyring not found: AttributeError("module 'keyring.backends.kwallet' has no attribute 'Keyring'")
DEBUG: [common/tools.py:895 keyringSupported] Metaclass keyring.backend.SecretServiceKeyring not found: AttributeError("module 'keyring.backend' has no attribute 'SecretServiceKeyring'")
DEBUG: [common/tools.py:897 keyringSupported] Metaclass keyring.backend.GnomeKeyring not found: AttributeError("module 'keyring.backend' has no attribute 'GnomeKeyring'")
DEBUG: [common/tools.py:899 keyringSupported] Metaclass keyring.backend.KDEKWallet not found: AttributeError("module 'keyring.backend' has no attribute 'KDEKWallet'")
DEBUG: [common/tools.py:910 keyringSupported] Available supported backends: [<class 'keyring.backends.SecretService.Keyring'>, <class 'keyring.backends.kwallet.DBusKeyring'>, <class 'keyring.backends.chainer.ChainerBackend'>]
DEBUG: [common/tools.py:913 keyringSupported] Found appropriate keyring 'keyring.backends.chainer'
DEBUG: [common/mount.py:73 Mount.__init__] pw-cache is not running
DEBUG: [common/mount.py:81 Mount.__init__] Call command: /usr/bin/backintime pw-cache start
DEBUG: [common/sshtools.py:285 SSH.startSshAgent] ssh-agent started successful: SSH_AUTH_SOCK=/tmp/ssh-XXXXXXeQTGaO/agent.13793 | SSH_AGENT_PID=13794
DEBUG: [common/sshtools.py:340 SSH.unlockSshAgent] Add private key /home/sg/.ssh/id_rsa to ssh agent
DEBUG: [common/sshtools.py:350 SSH.unlockSshAgent] Password available: True
ERROR: [common/sshtools.py:389 SSH.unlockSshAgent] Failed to unlock SSH private key /home/sg/.ssh/id_rsa: 
DEBUG: [common/sshtools.py:403 SSH.unlockSshAgent] Was not able to unlock private key /home/sg/.ssh/id_rsa

Hope this helps to hunt down the issue.

Sven

@68420948
Copy link

68420948 commented Mar 5, 2023

@aryoda, further tests revealed the above problem only appears when the "Cache Password for Cron" option is checked in the settings dialog.

@aryoda
Copy link
Contributor Author

aryoda commented Mar 5, 2023

THX a lot for testing my proposed fix with different scenarios!

The "Cache Password for Cron" setting is completely independent of the keyring:

The [ssh private key] password can be stored in users keyring.
The keyring is unlocked with the users password during login.
When running a scheduled backup-job while the user is not logged in, the keyring is not available.
For this case, the password can be cached in memory by Back in Time.

https://backintime.readthedocs.io/en/latest/settings.html#ssh

AFAIR the password cache uses ssh-agent to store the SSH private key password until a reboot or logout.

while unlocking the SSH private key fails.
Even after having stored the password anew (via the GUI) a restarted instance of BiT fails to unlock the SSH private key.

I need to exactly understand your testing scenario to investigate this:

  • I assume your ssh private key in /home/sg/.ssh/id_rsa is protected by a password
  • In the BiT config: Have you checked (enabled) both save password to keyring and cache password for cron or only one of the options?
  • When did the Could not unlock ssh private key. Wrong password or password not available for cron. appear after restarting BiT? When you started a backup via the GUI? Or via cron?
  • Did you restart BiT or even logged-out or even rebooted after storing the config and starting the backup?

Edit:

  1. To test if chainer is working only the save password to keyring should be checked
  2. Does the same error appear if you build BiT without the patch (= is it another bug?)?

@68420948
Copy link

68420948 commented Mar 5, 2023

The "Cache Password for Cron" setting is completely independent of the keyring:

I cannot confirm this. With BiT 1.3.3 and python3-keyring configured like

[backend]
default-keyring=keyring.backends.SecretService.Keyring

everything worked without issues for me.

AFAIR the password cache uses ssh-agent to store the SSH private key password until a reboot or logout.

This is correct. In addition two background processes are started.

I assume your ssh private key in /home/sg/.ssh/id_rsa is protected by a password

Correct.

In the BiT config: Have you checked (enabled) both save password to keyring and cache password for cron or only one of the options?

Both options have been checked.

When did the Could not unlock ssh private key. Wrong password or password not available for cron. appear after restarting BiT? When you started a backup via the GUI? Or via cron?

It happens when I start up the GUI for the first time after having logged in to the desktop. It is reproducible by killing the background process

python3 -Es /usr/share/backintime/common/backintime.py pw-cache start

and then starting up the GUI again.

Did you restart BiT or even logged-out or even rebooted after storing the config and starting the backup?

After having confirmed the error message it is enough to store the unchanged config again, without typing in the password. Every restart of Bit works fine as long as the pw-chache process is running. No backup have been started during all this.

  1. To test if chainer is working only the save password to keyring should be checked

With only "Save Password to Keyring" everything works flawlessly.

  1. Does the same error appear if you build BiT without the patch (= is it another bug?)?

No (see my first statement in this post posting).

I even cloned your repo https://github.com/aryoda/backintime and built branch 1410-add-chainer-keyring-support. This version of BiT shows the same behaviour as my patched Debian build. You should be able to reproduce things in your environment therefore.

Happy to help with more testing if needed.

@68420948
Copy link

68420948 commented Mar 5, 2023

More details:

The problem also disappears in case I start up the background process

python3 -Es /usr/share/backintime/common/backintime.py pw-cache start

explicitly from the command line, before calling backintime-qt.

@68420948
Copy link

68420948 commented Mar 5, 2023

@aryoda, please accept my apologies! All the above was result of my way testing things.

After a reboot of my machine my patched Debian package worked as expected.

Why killing the background process and then running backintime-qt behaves different is a separate issue.

@aryoda
Copy link
Contributor Author

aryoda commented Mar 5, 2023

@68420948 THX a lot for investing so much time (and no need to apology for anything, things are complicated and I have learned a lot debugging the source code and hope to write a little documentation about the password cache and keyring things one day)

Why killing the background process and then running backintime-qt behaves different is a separate issue.

We have an open issue with quite a similar observation (but still not reproducible on our side):

#1025 (comment)

I also had some strange effects with the pw cache but could not reproduce it so I could not find the the reason...

aryoda added a commit that referenced this issue Mar 5, 2023
@buhtz buhtz added this to the 1.3.4 milestone Mar 7, 2023
@aryoda
Copy link
Contributor Author

aryoda commented Jul 6, 2023

The fix was committed to the dev branch in March 5, 2023 so I close this issue now.

If a new problem should occur using the fixed version please open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug High Keyrings uses a keyring like kdewallet, SecretService, GnomeKeyring Reproduced
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

4 participants