proton-vpn-gtk-app
proton-vpn-gtk-app copied to clipboard
Locked Gnome keyring causes race condition and authentication denied
We are happy to answer your questions about the code or discuss technical ideas.
Please complete the following checklist (by adding [x]):
- [x] I have searched open and closed issues for duplicates
- [x] This isn't a feature request
- [ ] This is not a report about my app not working as expected
There's an issue when Gnome keyring is locked and it can be summarized as this:
- The Gnome keyring is locked
- Open the Proton VPN app
- Attempt to Quick Connect
- Proton attempts to connect
- nmcli prompts to unlock Gnome keyring
- While typing the keyring password Proton starts the network
- nmcli has no knowledge of any passwords because the keyring is locked and prompts to type OpenVPN credentials (see image below)
- Cancel OpenVPN credentials password request
- Finish typing the password, this will unlock Gnome keyring
- VPN connection failed with Authentication Error and internet access has been blocked
- Cancel current connection
- Attempt to Quick Connect
- Now the connection works because the Gnome keyring has been unlocked
I tried to trace the problem, but with so many callbacks and async everywhere it is hard.
There's one solution that works, but it might not be the best.
Here is my solution:
- In the file proton/vpn/backend/linux/networkmanager/core/networkmanager.py
- On the
start
method - Make a keyring call, this will prompt it to unlock it
- Type the password
- This will unlock Gnome keyring
- Connection works as expected
As the credentials and other data are stored in the keyring, ideally, in every new connection it should be checked if the keyring is locked or not. The user can manually lock it or another application can lock it.
What I have done in the code is:
diff --git a/proton/vpn/backend/linux/networkmanager/core/networkmanager.py b/proton/vpn/backend/linux/networkmanager/core/networkmanager.py
index 8fd7e55..a5b4149 100644
--- a/proton/vpn/backend/linux/networkmanager/core/networkmanager.py
+++ b/proton/vpn/backend/linux/networkmanager/core/networkmanager.py
@@ -116,6 +116,13 @@ class LinuxNetworkManager(VPNConnection):
self._notify_subscribers(events.Disconnected(EventContext(connection=self)))
return
+ try:
+ import keyring
+ k = keyring.get_keyring()
+ k.get_credential('ProtonVPN', 'ProtonUser')
+ except:
+ pass
+
try:
future_vpn_connection = self.nm_client.start_connection_async(connection)
vpn_connection = await loop.run_in_executor(
This solves my problem, but if this would be a valid solution, possibly it should be a call to Dbus.
Maybe the issue is somewhere else, it feels like a race condition, the VPN connection should not start while I type the keyring password to unlock the VPN credentials.
With some help, I could possibly patch this properly.