Open marmarek opened 9 years ago
Milestone justification: This feature is important for Whonix usability. (See https://github.com/QubesOS/qubes-issues/issues/1267.)
Likely a follow up issue:
One passive popup blocks another one. Example:
kdialog --passivepopup test1 ; kdialog --passivepopup test2
I.e. as long as the user does not click the first passive popup to make it go away, the second one will not be shown. So by not clicking the first one, the second passive popup will be lost unseen. A usability issue.
I am saying this, because until this ticket is implemented, I cannot implement what we planned for Whonix. (Which is "No more Tor bootstrap progress bar. + "Tor bootstrap in progress." passive poupup + "Tor bootstrap done." passive popup.) @bnvk @mfc
On Thu, Oct 08, 2015 at 08:22:34AM -0700, Patrick Schleizer wrote:
Likely a follow up issue:
I think this one is orthogonal to the ticket main topic. See below.
One passive popup blocks another one. Example:
kdialog --passivepopup test1 ; kdialog --passivepopup test2
I.e. as long as the user does not click the first passive popup to make it go away, the second one will not be shown. So by not clicking the first one, the second passive popup will be lost unseen. A usability issue.
So... use something that doesn't have this behaviour. kdialog --passivepopup
is some KDE specific mechanism, not using any standard
API (especially not freedesktop notification protocol). So even if we
implement "Centralized Tray Notifications", this wont affect kdialog
behaviour. Try notify-send
.
Note that some notification daemons have some limits on simultaneous
notifications (like gnome-notification-daemon
- 21, currently we use
mate-notification-daemon
, which AFAIR have much larger limit). What
happens with additional notifications is implementation specific, but in
most cases are lost, not queued.
One additional thing - maybe useful here - freedesktop notification
protocol supports retracting notifications (independent of setting some
timeout). So if one message, like "Connecting..." is no longer relevant,
it can be retracted (CloseNotification
dbus method) and/or replaced
(another Notify
with replaces_id
set) with another one.
AFAIR not all implementations support this feature. Also not sure if our
"Centralized Tray Notifications" will pass such messages.
Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing?
notify-send parameter --expire-time broken in Qubes
(#1297).On Thu, Oct 08, 2015 at 10:44:05AM -0700, Patrick Schleizer wrote:
- Looks like notify-send will do for Qubes-Whonix until this ticket gets implemented. Thanks you, Marek!
Not "until" - something needs to sent those notifications either to some
notification daemon, or to our "Centralized Tray Notifications".
kdialog
apparently doesn't do that, notify-send
(or other tools like
this) does.
Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing?
BTW check if notify-send
would also work on plain debian - AFAIR KDE
notification service also listens on that standard protocol.
Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing?
BTW check if
notify-send
would also work on plain debian - AFAIR KDE notification service also listens on that standard protocol.
notify-send works on Debian jessie KDE, but it looks weird.
Not "until" - something needs to sent those notifications either to some notification daemon, or to our "Centralized Tray Notifications".
kdialog
apparently doesn't do that,notify-send
(or other tools like this) does.
Not sure I understand. So once "Centralized Tray Notifications" is implemented, you'll be providing a tool that Whonix should start using? In that case, easy from Whonix side.
One additional thing - maybe useful here - freedesktop notification protocol supports retracting notifications (independent of setting some timeout). So if one message, like "Connecting..." is no longer relevant, it can be retracted (
CloseNotification
dbus method) and/or replaced (anotherNotify
withreplaces_id
set) with another one. AFAIR not all implementations support this feature. Also not sure if our "Centralized Tray Notifications" will pass such messages.
Yes. Very useful. I would very much like to implement this. But I can't.
notify-send(1) can't replace an existing notification
:
https://bugs.launchpad.net/ubuntu/+source/libnotify/+bug/257135
On Thu, Oct 08, 2015 at 10:51:47AM -0700, Patrick Schleizer wrote:
BTW check if
notify-send
would also work on plain debian - AFAIR KDE notification service also listens on that standard protocol.notify-send works on Debian jessie KDE, but it looks weird.
Hmm, just checked and here (Qubes dom0 with KDE) it looks exactly like the other KDE notifications. For that to work, "Notifications" widget needs to be added to panel. Anyway probably not worth further investigation.
Not "until" - something needs to sent those notifications either to some notification daemon, or to our "Centralized Tray Notifications".
kdialog
apparently doesn't do that,notify-send
(or other tools like this) does.Not sure I understand. So once "Centralized Tray Notifications" is implemented, you'll be providing a tool that Whonix should start using? In that case, easy from Whonix side.
We plan to implement it transparently to the VM applications. It will look like any other notification daemon, so for example notify-send (and any other application using standard API) would just work.
Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing?
Just doing a routine check: Is it still correct that @rootkovska is assigned to this issue?
No.
Also, there is a PoC written by @v6ak, linked and described in that qubes-devel thread
Thanks. Updated.
@v6ak, are you still working on this?
I am not working on this for multiple reasons. In short, I consider this to be much work for relatively low benefit:
So, I am able to discuss this if someone feels unsure about the design or my notes, but I don't plan to do this myself.
@v6ak: Understood. Thank you for all of your hard work so far and for your willingness to help anyone who might choose to take over on this!
It should be useful for any desktop environment - almost every DE have its own notification daemon, which uses the same D-Bus API. Anyway indeed UX impact isn't big here. On the other hand, having this service, and probably one more for simple confirmations would allow having gpg backend domains without X server running at all (-> much lower memory footprint).
Yes, it should work for (almost) any DE, I just found it more useful with KDE than with XFCE. Provided that there are no concurrent notifications from different VMs (I've found such cases rare) and all the VMs use the same notification daemon, there might be nothing wrong with UX. The KDE notification daemon provides some Android-like notification history (I like the idea, though I've not verified if it is really useful), which makes sense to have just in one VM.
The GPG backend is a good point. Maybe it could be the starting point for wide deployment (i.e. enabled by default), as it is a bounded usecase, so most UX issues should be immediately apparent.
Also unikernels might want to use it. However, I don't feel it would be good to start there, because this could lead to a protocol that is not well-mappable to libnotify.
However, centralized notifications might be a prerequisite for implementing a reasonable focus-stealing protection.
Cool. Recently, I got a larger screen, where I feel the need for a better notification system* (dunst). And having a single notification daemon is much easier to handle. So:
*) Notification system is useless when you can't see notification on right side of the screen because you are looking at the left side and the notification pop-up is too small to notice by peripheral vision.
There is some VM part into https://github.com/nastaziya/dbus-notify. @v6ak: I did some refactor of the dom0/GuiVM part: https://github.com/fepitre/qubes-core-admin/commit/fa1c2091beedb9e4e3f63713e870960edfe6f737. I'm about to extract the service part running in VM in the dbus-notify repository. If you want to have a look too and post comments here that would help. Thank you.
I just pushed picked and refactored code from https://github.com/nastaziya/dbus-notify which original work is from your POC @v6ak. The WIP VM part is https://github.com/fepitre/qubes-core-agent-linux/commit/cbe8f5911080d031d0bf0496bfe7b3ce90573718. Please not the packaging is note finished and not validated yet.
@v6ak thanks to your POC, i just nedded to replace the bash RPC endpoint by a python script as you suggested here. The notification-daemon didn't change much (I just added a "protocol" to handle newlines in notification title/body, which changes the way of sending the notification). Note: for xfce desktop env. you have to stop xfce4-notifyd before launching 'qubes-domu-dbus-notification-daemon' (it is not the case if you are using Gnome desktop with mate-notification-daemon)
In its most rudimentary form, qubes.TrayNotification will display only the source app name, the source VM name, summary and body, but there is also a version that uses the app icon already here for the appmenu usage (which is a safe solution for lazy readers). In order to have the icon in the app notification, the app must appear in the VM's appmenu.
@andrewdavidwong should this be bumped to critical based on #2026 as well? since either this or #1917 should resolve #2026.
@andrewdavidwong should this be bumped to critical based on #2026 as well? since either this or #1917 should resolve #2026.
My thought was that #1917 was the preferred solution to the main topic we were discussing in #2026 (namely, having a secure screen locking solution in Qubes), whereas this (#889) has its own motivation and is not primarily about screen locking.
However, I have no problem with bumping this up to critical, and @marmarek can always adjust the priority back down if he sees fit.
Hi, I've looked at @nastaziya's version, tried it and adjusted a bit. I'd like to do some more adjustments. My notes:
WantedBy=default.target
in order to be enablable.After my adjustments, Chromium and Firefox accept the notification daemon. Without my modifications, it is ignored and they use their own GUI for notifications. Well, I've cheated a bit, as Chromium refuses to use notification daemon that does not announce support for actions, but I haven't implemented them…
I'd like to implement actions and close notifications, which both need a backward channel. I see two options:
a. Keep the GuiVM side one-process-per-notification and keep the process until the notification is closed. b. Make a daemon in GuiVM that handle all the notifications and make backward Qubes RPC call when needed (notification closed / action clicked). Of course, this require more RPC calls and makes the policy more complicated. Well, we still need to create a process per notification (this is by design of Qubes RPC), and we would create more processes and RPC calls, but our processes would be rather short-lived. c. Like b, but the daemon would be per-qube.
Maybe A is the simplest option.
Also one organizational question: What repo/branch should I target with PRs? Is it https://github.com/fepitre/qubes-core-agent-linux/tree/notification-daemon ?
Also one organizational question: What repo/branch should I target with PRs? Is it https://github.com/fepitre/qubes-core-agent-linux/tree/notification-daemon ?
You can cherry-pick the needed commits then open PR on QubesOS master branch directly. My branch is a brief summary/refactor of previous authors work.
a. Keep the GuiVM side one-process-per-notification and keep the process until the notification is closed.
Yes, make it one call per notification. It doesn't strictly need to be a one process, a single process can handle multiple calls with socket-based service (https://www.qubes-os.org/doc/qrexec-socket-services/). In Python or other high-level language, it should be easy to do safely. But the initial version can use one process per notification.
Also one organizational question: What repo/branch should I target with PRs?
A new repository (qubes-app-notification-daemon)? core-agent-linux would be almost good, but it isn't for dom0 and we still need the backend part in dom0. Alternatively, split between gui-agent-linux/gui-daemon, but then I'd make it separate subpackage. it should be possible to use it (the frontend side) without starting X server and preferably without even forcing it being installed (so, cannot depend on gui-agent main package). In fact, some of my qubes have X server running only because of the notifications (VPN qube being such example).
And also, thanks @v6ak for picking up this task!
I fear the design is slightly flawed:
Why do notifications have to be processed in dom0 at all?
They might required to be displayed there without GUI VM, but the string processing, dbus
and libnotify
code does not need to be executed there. Also, you don't want that fancy notification tray icon program of your choice with 1000 bugs to be executed in dom0 (where it is never updated).
So contrary to the proposal by @fepitre all code should go to qubes-core-agent-linux
(or a dedicated package) with the receiving notification VM being configurable via e.g. qubesdb
(default to sys-firewall
or some dedicated sys-notify
VM?). Only the RPC policy would go to dom0 / qubes-core-admin
.
@v6ak Also please don't implement the backchannel as it can become a security nightmare. It can e.g. easily be used for a covert channel from the notification target VM to all other VMs on a system. Unidirectional will keep it a lot more simple and likely more secure. If necessary, once could just locally (without qrexec
call in the sender VM) reply to the notification sender that the notification was closed after the expected timeout regardless of what happened in reality.
Otherwise the code mostly looked reasonable to me (I looked at the refactor by @fepitre).
As an additional feature maybe the sender VM could pick from a pre-defined set of icons or one could simply call notify-send
in the receiving VM and re-use the standard notify-send
icons.
The spec for reference: https://developer.gnome.org/notification-spec/
I fear the design is slightly flawed: Why do notifications have to be processed in dom0 at all? They might required to be displayed there without GUI VM, but the string processing,
dbus
andlibnotify
code does not need to be executed there. Also, you don't want that fancy notification tray icon program of your choice with 1000 bugs to be executed in dom0 (where it is never updated).
As a general rule, Qubes OS assumes that merely displaying untrusted text is not a security issue, provided that said text is limited to a subset of ASCII. Transmitting an opaque bitmap (instead of a string) would lead to a significantly more complicated and bug-prone protocol. Nevertheless, the notification tray icon program will need to be audited to ensure it treats the input as a plain text string, and does not try to parse it as markup.
So contrary to the proposal by @fepitre all code should go to
qubes-core-agent-linux
(or a dedicated package) with the receiving notification VM being configurable via e.g.qubesdb
(default tosys-firewall
or some dedicatedsys-notify
VM?). Only the RPC policy would go to dom0 /qubes-core-admin
.
This could be a significant limitation in some cases. For instance, GNOME Shell has built-in notification support. Requiring notifications to be in a separate qube could lead to a significantly inferior user experience if GNOME is adopted. Furthermore, a good notification widget might require special privileges, such as being able to display in areas forbidden to most qubes.
@v6ak Also please don't implement the backchannel as it can become a security nightmare. It can e.g. easily be used for a covert channel from the notification target VM to all other VMs on a system. Unidirectional will keep it a lot more simple and likely more secure. If necessary, once could just locally (without
qrexec
call in the sender VM) reply to the notification sender that the notification was closed after the expected timeout regardless of what happened in reality.
Covert channels (which require cooperation between qubes) are generally out of scope for Qubes OS. It is already possible for cooperating qubes to establish a communication channel via Xen grant tables, and even if this was blocked, current x86 hardware makes preventing covert channels infeasible. This is distinct from side channels, where one qube is trying to steal data from an uncooperative qube. Meltdown and Spectre fall into the latter category.
Furthermore, I suspect being able to include one or more actions in a notification is quite useful from a user experience perspective. @ninavizz what are your thoughts?
Oh dear, I have many, many thoughts on needs to improve notifications in Qubes. @v6ak I am not a developer, but a UX practitioner. As such, I have nooo idea how to "check out" code to preview things. But, I would be totally down to chat with you about this work! I know nothing about security stuff, so leave that guidance to others... but how notifications are exposed to users, with what text, and possible actions, yes, I have many thoughts about!
Please let me clarify more expressively (I usually use very little, but meaningful words, sorry for that):
Transmitting an opaque bitmap [...]
I wasn't suggesting to transfer a bitmap. I was suggesting to transfer an identifier (string, number, wahtever) that results in the display of a pre-installed trusted bitmap in the target VM. So e.g. if the sender VM transfers a "1", the receiver VM will display an icon that reflects that identifier in both of the sender and receiver code.
GNOME Shell has built-in notification support [...]
A lot of apps have via the spec I mentioned, but I'm not sure how that's related to the dom0 vs domU argument. It works with both.
The current architecture ("decentralized"):
notification sender (sender VM) -->
notification server (sender VM) displays small window
The architecture I propose ("centralized domU"):
notification sender (sender VM) -->
notification server (sender VM) uses qrexec to forward to domU -->
qrexec receiver (target VM) does sanitization and creates a new local notification -->
some standard fancy locally running notification server displays it
The architecture visible in the aforementioned code ("centralized dom0"):
notification sender (sender VM) -->
notification server (sender VM) uses qrexec to forward to dom0 -->
qrexec receiver (dom0) does sanitization and creates a new local notification -->
some notification server in dom0 displays it
I'm against running too much stuff in dom0. I hope we can align on that.
Both are identical wrt UX.
Covert channels [...]
There's always a balance between security and UX. I was attempting to cut minor UX features for the sake of security there (bidirectional vs unidirectional protocol architecture). It's not my decision to make though, good point.
@3hhh How is bidirectional vs unidirectional protocol architecture in any way experienced by the end user?
How is bidirectional vs unidirectional protocol architecture in any way experienced by the end user?
We were talking about the org.freedesktop.Notifications.NotificationClosed
and org.freedesktop.Notifications.ActionInvoked
signals of the desktop notification spec there.
For NotificationClosed
an affected app might believe that a notification is still displayed while in fact it is already gone. The impact depends on the application which sent the notification, but will at most last a few seconds.
For ActionInvoked
the app might not be informed that the user clicked somewhere on the notification. Buttons are uncommon in notifications and I've never seen any, so I dismiss that impact.
Moreover even the spec says: "Clients should not assume the server will generate this signal. Some servers may not support user interaction at all, or may not support the concept of being able to "invoke" a notification."
EDIT: Bidirectional would support these two (from my point of view weird) signals. Unidirectional would provide a basic local implementation for NotificationClosed
and none for ActionInvoked
, but have some security benefits from to the one-way communication channel.
For
ActionInvoked
the app might not be informed that the user clicked somewhere on the notification. Buttons are uncommon in notifications and I've never seen any, so I dismiss that impact.
Interesting! I know that on mobile, buttons on notifications (such as “reply to message”) are extremely common, so I was surprised that they are rare on desktop.
For
ActionInvoked
the app might not be informed that the user clicked somewhere on the notification. Buttons are uncommon in notifications and I've never seen any, so I dismiss that impact.Interesting! I know that on mobile, buttons on notifications (such as “reply to message”) are extremely common, so I was surprised that they are rare on desktop.
My desktop GMail notifications, I believe include a "Reply" button. Likewise, I've seen buttons included in updater messages. The option to "Bug me later" vs to outright "Dismiss" an update notification, also feels very important for an OS like Qubes.
Buttons imply richer interactivity options that most of Qubes OS currently has. Qubes is special because of the many things it simply makes possible short of running a dozen physically-airgapped devices, at once. For "notifications" that do include buttons, I see the Qubes "Question" window as basically fulfilling that goal—but with the workaround of being a small dialog box.
I'd much prefer those eventually become notification bubbles spawned by dedicated widgets for Split-GPG and Inter-Qube activities. I'll put that on my list for "Things Nina Wants When Millions Of Dollars Fall From The Sky."
On Fri, Jul 09, 2021 at 02:55:22PM -0700, Nina Eleanor Alter wrote:
For
ActionInvoked
the app might not be informed that the user clicked somewhere on the notification. Buttons are uncommon in notifications and I've never seen any, so I dismiss that impact.Interesting! I know that on mobile, buttons on notifications (such as ???reply to message???) are extremely common, so I was surprised that they are rare on desktop.
My desktop GMail notifications, I believe include a "Reply" button. Likewise, I've seen buttons included in updater messages. The option to "Bug me later" vs to outright "Dismiss" an update notification, also feels very important for an OS like Qubes.
Buttons imply richer interactivity options that most of Qubes OS currently has. Qubes is special because of the many things it simply makes possible short of running a dozen physically-airgapped devices, at once. For "notifications" that do include buttons, I see the Qubes "Question" window as basically fulfilling that goal???but with the workaround of being a small dialog box.
I'd much prefer those eventually become notification bubbles spawned by dedicated widgets for Split-GPG and Inter-Qube activities. I'll put that on my list for "Things Nina Wants When Millions Of Dollars Fall From The Sky."
NM notifications have a "Don't tell me about this again" option. I would like to see similar on the "qube starting" and "qube shutting down" notifications, or a mechanism to mute them.
The dialog box not only asks the question, but also provides interaction (in selecting a target qube) - I don't see how a bubble could provide that, and users are likely used to such dialog boxes in any case.
Most of the aforementioned examples ("Bug Me later", "Dismiss", "Don't show this again", ...) are matters of the notification server implementation in the target VM (aka the fancy stuff with potentially 1k bugs I mentioned earlier). A good overview can be found at the arch wiki.
Only this "Reply to e-mail" button would require a working ActionInvoked
implementation, i.e. a backchannel. If that's really required, I'd suggest to set ask
or deny
as RPC default to avoid a bidirectional default communication channel between all VMs and their notification server VM. One could still change it for dedicated VMs.
Alternatively, one could just handle such notifications via the locally running notification server, i.e. fall back to the decentralized architecture for those.
After looking into dbus
details a bit, I think it would be possible to intercept notifications as man-in-the-middle on the bus and selectively forward the ones that one wants to a different VM via qrexec
.
This would have the advantage that one could keep the local desktop notification server running (i.e. remain backwards compatible) and show notifications locally when there are e.g. buttons inside of them.
It would however require the running daemon to locally close notifications that were forwarded unless one wants them to be displayed both locally and in the other VM.
Here's a rough code sample that works on older dbus
versions (non-Fedora). Fedora apparently requires the newer BecomeMonitor
method.
After looking into
dbus
details a bit, I think it would be possible to intercept notifications as man-in-the-middle on the bus and selectively forward the ones that one wants to a different VM viaqrexec
.This would have the advantage that one could keep the local desktop notification server running (i.e. remain backwards compatible) and show notifications locally when there are e.g. buttons inside of them.
It would however require the running daemon to locally close notifications that were forwarded unless one wants them to be displayed both locally and in the other VM.
Here's a rough code sample that works on older
dbus
versions (non-Fedora). Fedora apparently requires the newerBecomeMonitor
method.
I tested this approach with Firefox.
Unfortunately the race condition when closing the local notification results in the notification being displayed locally for ~1s. So this is not usable.
Strangely it works just fine with notify-send
.
As an alternative xdg-dbus-proxy
aims to fully proxy dbus, but appears to be rather broken and unmaintained.
It would be great to be able to handle some notifications locally (e.g. the ones with buttons), but dbus
only allows one implementation to provide a service/interface at a time and it seems that you cannot directly call a previously registered implementation once you claim an interface for yourself.
So to make notification forwarding work with arbitrary applications Qubes has the following choices:
mate-notification-daemon
), align on it for all VMs and insert some qrexec
calls in it for the select group of messages that one wishes to forward.qrexec-client-vm
for certain notifications instead of displaying them locally (e.g. dunst
does this, but doesn't support buttons and icons itself).dbus
instance via dbus-launch
for the local notification daemon beforehand and selectively forward messages to that bus).qrexec-client-vm
), and fallback to "full" notification server for complex calls via spawning separate dbus-daemon instance (on a different address) with just (real) notification server there.As for where the real notification server should run, GUI qube (which may be dom0) sounds like a logical choice, as some desktop environments have pretty tightly integrated notifications (AFAIR KDE has a built in widget that allows to review notification history too). Coincidentally, having a back channel (actions) from a GUI qube is less of an issue, as it already has a way to send data to any VM connected to it. Another qube could also be an option, especially if considering more complex features, but I don't like to put too much stuff (especially GUI related) to sys-firewall, as I'd like to make it as lightweight as possible (including possibility to use MirageOS-based one without GUI at all).
(*) Actually, sound could be handled locally, without sending it over to the notification VM.
Reported by joanna on 18 Aug 2014 14:59 UTC A simple qubes.TrayNotification service in Dom0/GUI domain that would be trigerable by agents in each VM (which would register as default tray notifcator). The protocol should be trivial -- just a fixed-size string, sanitized by the server in the usual way (same as we do for Windows titles, etc).
Migrated-From: https://wiki.qubes-os.org/ticket/889
Historical information about contributors
**Community Dev:** @v6ak, @nastaziya, @fepitre **Partial PoC:** https://groups.google.com/d/msg/qubes-devel/1Lzv9SQCzFc/4gKx06iKRD4J **Discussion:** https://groups.google.com/d/topic/qubes-devel/1Lzv9SQCzFc/discussion