ErikReider / SwayNotificationCenter

A simple GTK based notification daemon for SwayWM
GNU General Public License v3.0
1.3k stars 62 forks source link

[feature req] Persistence across restart #163

Open 1ace opened 2 years ago

1ace commented 2 years ago

It would be great if it was possible to store the notifications when receiving them (and clearing that state when closing them), so that restarting swaync (or rebooting) doesn't lose all unhandled notifications but instead lists them again.

ErikReider commented 2 years ago

I've tried adding this feature but I'm not really sure how it would be done securely. Do you have any suggestions?

1ace commented 2 years ago

By "securely", I assume you mean that the content of the notification might be sensitive and storing it on disk has the risk of a third party reading it back?

Would a simple obfuscation (eg. xor with a simple bit pattern like 0x55) work? It would protect against techniques like string scanning, but not against a targetted attack against swaync (but being open source nothing would, short of cryptography with a private key generated by each user).

1ace commented 2 years ago

I don't know Vala, but I wrote a quick example in C:

#include <stdio.h>

int main(const int argc, const char* argv[])
{
  if (argc <= 1) {
    printf("Usage: %s 'string to write'\n", argv[0]);
    return 1;
  }

  FILE* example = fopen("example", "wb");

  unsigned c = 0;
  while (argv[1][c]) {
    // (char ^ 0xff) => toggling all the bits
    // replace with any smaller (non-zero) value
    // to only toggle some of the bits
    fprintf(example, "%c", argv[1][c] ^ 0xff);
    c++;
  }

  fclose(example);
  return 0;
}
$ echo -n the quick brown fox jumps over the lazy dog > example
$ xxd example
00000000: 7468 6520 7175 6963 6b20 6272 6f77 6e20  the quick brown 
00000010: 666f 7820 6a75 6d70 7320 6f76 6572 2074  fox jumps over t
00000020: 6865 206c 617a 7920 646f 67              he lazy dog
$ cc example.c
$ ./a.out "the quick brown fox jumps over the lazy dog"
$ xxd example
00000000: 8b97 9adf 8e8a 969c 94df 9d8d 9088 91df  ................
00000010: 9990 87df 958a 928f 8cdf 9089 9a8d df8b  ................
00000020: 979a df93 9e85 86df 9b90 98              ...........
ErikReider commented 2 years ago

Hmmm, interesting! I'll look into it :)

bd-g commented 1 year ago

Considering any process can just subscribe to system notifications, I'm not sure if overly securing them is entirely necessary.

I'm looking at other applications' approaches, and many just have a SQLite3 file stored under .config.

If we went this direction, if one wanted to protect against access to historical notifications, having your main partitions encrypted when your laptop is off should do the trick, but that is up to each individual user.

ErikReider commented 1 year ago

Using a SQL db would be feasible but I'll have to look into it. Help would be appreciated! :)

ErikReider commented 1 year ago

So two things need to be tackled before starting this. How will we handle Images sent through image_data/icon_data and replacing notifications (finding the correct notification to replace).

bd-g commented 1 year ago

I believe you could just store the image as a BLOB in the SQLite database along with the rest of the notification data.

What exactly do you mean by "finding the right notification to replace"?

ErikReider commented 1 year ago

I believe you could just store the image as a BLOB in the SQLite database along with the rest of the notification data.

Seems a bit messy for an initial implementation. I'll stick with the essentials (most strings and integers) for the time being and save image data for a later implementation.

What exactly do you mean by "finding the right notification to replace"?

To replace a notification with another one, the application must provide a replaces_id which must match a already sent notification id. Swaync keeps count of all notifications to then replace the correct one, but it always starts at 0.

If we were to save each notification to the DB as they appear, finding the correct notification in the DB would be difficult. Maybe setting the ID of past notification to -1/null on startup would make this easier, but then the notifications id wouldn't be the tables primary key