Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ encrypted file. There is no account and no service behind it: it works
entirely offline, and if you want two PCs in step you run the sync server
yourself, on your own hardware.

**Version 0.3.0 — early.** It installs from a `.deb` on Ubuntu 22.04 or
**Version 0.6.0 — early.** It installs from a `.deb` on Ubuntu 22.04 or
newer, or runs from source. It has so far been tested in CI only, on a
virtual display, not yet on a real desktop.

Expand All @@ -19,7 +19,8 @@ virtual display, not yet on a real desktop.
| [PassMan-Server-Linux](https://github.com/usermaneGermane/PassMan-Server-Linux) | the sync server for Linux, run by systemd |

**Same vaults as on Windows.** The vault file, the sync protocol and the
features are those of PassMan for Windows 2.4.0, which this was ported from.
features match PassMan for Windows 2.8.0, except the 2.7.0 redesign, which is
not ported yet (see *What is different from Windows*).
A vault moves between a Windows PC and a Linux PC unchanged, and both sync
with either server.

Expand Down Expand Up @@ -107,6 +108,7 @@ screen if you sync.
- **Clipboard.** PassMan uses Tk's own clipboard, so nothing like `xclip`
needs installing. It works on X11 and, through XWayland, on Wayland. On
X11 what PassMan copied disappears when PassMan closes. As on Windows,
locking leaves a copied password pasteable, closing clears it at once, and
copied passwords are cleared after 30 seconds — but a clipboard manager
(GNOME or KDE clipboard history, CopyQ, …) may keep its own copy, which
no application can reach.
Expand All @@ -130,6 +132,8 @@ Where that README names a Windows version, read the Linux one beside it:
| 2.4.0 | 0.3.0 | deleting archived entries after N days |
| 2.5.0 | 0.4.0 | switching servers no longer removes entries silently |
| 2.6.0 | 0.5.0 | a copy that is not installed says LAB in its title |
| 2.7.0 | not yet | the redesigned window |
| 2.8.0 | 0.6.0 | locking no longer clears a copied password |

(0.2.0 added the `.deb` package, which has no Windows counterpart.)

Expand Down
6 changes: 2 additions & 4 deletions sourceFiles/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -846,10 +846,8 @@ def lock_vault(self, auto=False):
self._cancel_idle_timer()
if self.master_password and self.current_user:
self._save()
if self._clip_text is not None:
if self._clip_job:
self.root.after_cancel(self._clip_job)
self._clear_clipboard(self._clip_text, quiet=True)
# A copied password outlives the lock: the usual auto-clear timer
# keeps running, so it can still be pasted until that fires.
self.vault = self.master_password = self.current_user = None
self._history_open.clear()
self.search_query = ""
Expand Down
58 changes: 58 additions & 0 deletions sourceFiles/tests/test_clipboard_lock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""
Locking the vault leaves a copied password on the clipboard.

The auto-clear timer started by the copy keeps running, so the password can
still be pasted after a lock until that timer fires.
"""

import pytest

gui = pytest.importorskip("gui", reason="needs tkinter (bundled with Python)")


class FakeRoot:
def __init__(self):
self.cancelled = []

def after_cancel(self, job):
self.cancelled.append(job)


class FakeApp:
"""Just enough of PasswordManagerGUI for lock_vault to run."""

lock_vault = gui.PasswordManagerGUI.lock_vault

def __init__(self):
self.root = FakeRoot()
self.master_password = None # nothing unlocked → no save
self.current_user = None
self.vault = {}
self._clip_text = "s3cret"
self._clip_job = "clear-job"
self.cleared = []
self._history_open = set()

def _cancel_idle_timer(self):
pass

def show_login_screen(self):
pass

def toast(self, message, kind="info"):
pass

def _clear_clipboard(self, expected, quiet=False):
self.cleared.append(expected)


@pytest.mark.parametrize("auto", [False, True])
def test_lock_keeps_the_copied_password_and_its_timer(auto):
app = FakeApp()

app.lock_vault(auto=auto)

assert app.cleared == []
assert app.root.cancelled == []
assert app._clip_job == "clear-job"
assert app._clip_text == "s3cret"
2 changes: 1 addition & 1 deletion sourceFiles/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
format changes.
"""

__version__ = "0.5.0"
__version__ = "0.6.0"

#: Container version PassMan writes today (see crypto_utils.MAGIC).
VAULT_FORMAT = "PMV2"
Expand Down
Loading