Skip to content

Feature/lock db on session lock #134#135

Closed
rockdreamer wants to merge 6 commits intokeepassxreboot:developfrom
rockdreamer:feature/lock-db-on-session-lock-#134
Closed

Feature/lock db on session lock #134#135
rockdreamer wants to merge 6 commits intokeepassxreboot:developfrom
rockdreamer:feature/lock-db-on-session-lock-#134

Conversation

@rockdreamer
Copy link
Copy Markdown
Contributor

Description

  • Added a configuration entry in general settings called "Close database when session is locked or lid is closed"
  • Added a class called ScreenLockListener with a private implementation class backed by three platform specific implementations:
    • on Mac OS the implementation uses the NSNotificationCenter C API
    • on Linux the implementation listens to DBus signals
    • on Windows the implementation registers for platform specific messages and registers a platform message handler

Motivation and Context

Implementation of issue #134

How Has This Been Tested?

I have tested on the following platforms:

  • Mac OS Sierra, Qt 5.7 from online installer, XCode 8, physical laptop: Lid close triggers lock
  • Ubuntu 16.10, Qt 5.7 from online installer, on Unity desktop, virtual machine: Session lock triggers lock
  • Windows 7, Qt 5.7 from online installer with libraries from MSYS2, virtual machine: Session lock triggers lock

Screenshots (if appropriate):

Types of changes

  • ❎ Bug fix (non-breaking change which fixes an issue)
  • ✅ New feature (non-breaking change which adds functionality)
  • ❎ Breaking change (fix or feature that would cause existing functionality to change)

This change brings in the following new dependencies:

  • Mac OS: Foundation framework (always present on the platform), the build requires XCode 8
  • Linux: Qt::DBus (available on most Linux distributions nowadays)
  • Windows: wtsapi32.lib (part of the platform SDK)

Checklist:

  • ✅ I have read the CONTRIBUTING document. [REQUIRED]
  • ✅ My code follows the code style of this project. [REQUIRED]
  • ✅ All new and existing tests passed. [REQUIRED]
  • ❎ My change requires a change to the documentation.
  • ❎ I have updated the documentation accordingly.
  • ❎ I have added tests to cover my changes.

this, //receiver
SLOT(unityLocked()));

/* Currently unable to get the current user session from login1.Manager
Copy link
Copy Markdown
Contributor

@TheZ3ro TheZ3ro Dec 31, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are this comments useful or they can be removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi TheZ3ro and Happy new year :)
I would remove the comment and add a separate issue.
In theory the login1.Manager interface should provide a common API for handling session status notifications, however I had issues making it work. when I passed the current pid to the getsession call, it wouldn't return a valid session url. Maybe it only works on consoles but it would be nice if it worked across desktop managers.
Once this issue is resolved, I would de-comment and add a signal listener on the returned session much like what is currently done for unity, gnome session etc.

@TheZ3ro
Copy link
Copy Markdown
Contributor

TheZ3ro commented Dec 31, 2016

I think it's appropriate moving the option under the Security configuration screen. All the configurations that interacts with the DB are placed there.

The code seems good, I will test this in the next few days.
(Happy 2017 to all the project contributors and maintainers 🎉 )

widget.
Changed wording and preference variable name for conformity with
existing settings.
@TheZ3ro
Copy link
Copy Markdown
Contributor

TheZ3ro commented Jan 1, 2017

Tested on my Ubuntu/XFCE/LightDM. When I lock the screen KeePassXC doesn't lock.

The only dbus signal emitted on locking is this:

signal time=1483283213.169993 sender=:1.0 -> destination=(null destination) serial=4200 path=/com/ubuntu/Upstart; interface=com.ubuntu.Upstart0_6; member=EventEmitted
   string "bdi-device-added"
   array [
      string "KERNEL=0:46"
      string "DEVPATH=/devices/virtual/bdi/0:46"
      string "SUBSYSTEM=bdi"
      string "ACTION=add"
      string "SEQNUM=7951"
      string "USEC_INITIALIZED=1564711295871"
   ]
signal time=1483283218.842816 sender=:1.0 -> destination=(null destination) serial=4201 path=/com/ubuntu/Upstart; interface=com.ubuntu.Upstart0_6; member=EventEmitted
   string "bdi-device-removed"
   array [
      string "KERNEL=0:46"
      string "DEVPATH=/devices/virtual/bdi/0:46"
      string "SUBSYSTEM=bdi"
      string "ACTION=remove"
      string "SEQNUM=7952"
      string "USEC_INITIALIZED=1564716968162"
   ]

So I think we should add more DBus signal

Under xUbuntu/XFCE:
interface=com.ubuntu.Upstart0_6; path=/com/ubuntu/Upstart; member=EventEmitted

Under KDE it's something like: source
interface=org.freedesktop.ScreenSaver, path=/org/freedesktop/ScreenSaver, member=GetActive

Under Cinnamon something like: source
interface=org.cinnamon.ScreenSaver, path=/org/cinnamon/ScreenSaver

I think we should cover them all (unfortunately)

@phoerious
Copy link
Copy Markdown
Member

phoerious commented Jan 19, 2017

I did a little research and downloaded a couple of live systems to have look at what D-Bus signals are emitted on different distributions.

I guess it would be enough to add

// ...

    sessionBus.connect(
                "org.freedesktop.ScreenSaver", // service
                "/org/freedesktop/ScreenSaver", // path
                "org.freedesktop.ScreenSaver", // interface
                "ActiveChanged", // signal name
                this, //receiver
                SLOT(freedesktopScreenSaver(bool)));

// ...

void ScreenLockListenerDBus::freedesktopScreenSaver(bool status)
{
    if (status)
        Q_EMIT screenLocked();
}

That locks the database on my main KDE system and the same signal is also emitted in the Manjaro XFCE VM I tried. Looks like this is the freedesktop.org standard interface, unfortunately not implemented by all desktop environments.

com.canonical.Unity.Session appears redundant to me because apparently, Ubuntu also sends org.gnome.SessionManager.Presence. Also the member name Locked seems to be incorrect. At least my 16.10 Ubuntu VM used Lock instead. If you are Ubuntu users, you can maybe test if everything still works if you remove the connection to com.canonical.Unity. If that is the case, I would prefer to remove it and only use the org.gnome.SessionManager.Presence interface for Unity or Gnome-based distributions.

I did not test org.freedesktop.login1.Manager because I couldn't get the live system in my VM to suspend and resume properly.

Additionally, I think we should enable the option to lock the database when the screen is locked by default. You shouldn't accidentally leave your password database unlocked when you leave the PC.

Copy link
Copy Markdown
Member

@phoerious phoerious left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added what I summarized in the posting above as inline comments. Please have a look.

m_secUi->lockDatabaseIdleCheckBox->setChecked(config()->get("security/lockdatabaseidle").toBool());
m_secUi->lockDatabaseIdleSpinBox->setValue(config()->get("security/lockdatabaseidlesec").toInt());
m_secUi->lockDatabaseMinimizeCheckBox->setChecked(config()->get("security/lockdatabaseminimize").toBool());
m_secUi->lockDatabaseOnScreenLockCheckBox->setChecked(config()->get("security/lockdatabasescreenlock").toBool());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enable this option by default.

HWND h= reinterpret_cast<HWND>(static_cast<QWidget*>(parent())->winId());
WTSUnRegisterSessionNotification(h);

if(m_powernotificationhandle){
Copy link
Copy Markdown
Member

@phoerious phoerious Jan 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coding style, please add a space after if. Also applies to the following if conditions in this file. Also add spaces before opening braces.

}
}
if(m->message == WM_WTSSESSION_CHANGE){
if (m->wParam==WTS_CONSOLE_DISCONNECT){
Copy link
Copy Markdown
Member

@phoerious phoerious Jan 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again coding style, please add spaces around == operators and before opening braces.

Q_EMIT screenLocked();
return true;
}
if (m->wParam==WTS_SESSION_LOCK){
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

private Q_SLOTS:
void gnomeSessionStatusChanged(uint status);
void logindPrepareForSleep(bool beforeSleep);
void unityLocked();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add

    void freedesktopScreenSaver(bool status);

unityLocked() probably not needed.

void ScreenLockListenerDBus::unityLocked()
{
Q_EMIT screenLocked();
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add

void ScreenLockListenerDBus::freedesktopScreenSaver(bool status)
{
    if (status)
        Q_EMIT screenLocked();
}

}
}

void ScreenLockListenerDBus::unityLocked()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not needed.

this, //receiver
SLOT(logindPrepareForSleep(bool)));

sessionBus.connect(
Copy link
Copy Markdown
Member

@phoerious phoerious Jan 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

com.canonical.Unity probably not needed.

"StatusChanged", // signal name
this, //receiver
SLOT(gnomeSessionStatusChanged(uint)));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add

    sessionBus.connect(
                "org.freedesktop.ScreenSaver", // service
                "/org/freedesktop/ScreenSaver", // path
                "org.freedesktop.ScreenSaver", // interface
                "ActiveChanged", // signal name
                this, //receiver
                SLOT(freedesktopScreenSaver(bool)));

@droidmonkey
Copy link
Copy Markdown
Member

Ping @rockdreamer , this pr needs a fair bit of work. Are you still interested in contributing to it?

@droidmonkey
Copy link
Copy Markdown
Member

I believe this PR has become overcome by #545. Recommend closing.

@droidmonkey droidmonkey removed this from the v2.2.0 milestone May 7, 2017
@TheZ3ro TheZ3ro closed this May 7, 2017
@phoerious phoerious added pr: new feature Pull request adds a new feature and removed new feature labels Nov 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants