-
-
Notifications
You must be signed in to change notification settings - Fork 440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Matrix notifications could be end-to-end encrypted #305
Comments
Hi @uuksu, You definitely have a great feature request here, but I'm not sure where to even start 😕 . Even the official Matrix Python SDK doesn't even support this functionality (see here - they closed the ticked as won't fix). Another link on the matrix.org website here points to an archived repository (not maintained at all) that provides olm bindings (what is needed to encrypt the messages) here. Even as an unmaintained library, it's still available on PyPi; so this part is awesome!.... However... The second problem is is that it doesn't work at all; you can't include it.... 🙁 # I'm using Python v3.7 with this call (Fedora 31)
pip install python-olm Collecting python-olm
Downloading https://files.pythonhosted.org/packages/d4/a4/1face47e65118d7c52726dfa305410a96bc4a0c6f3f99c90bc7104aebf21/python-olm-3.1.3.tar.gz
Requirement already satisfied: cffi>=1.0.0 in ./lib/python3.7/site-packages (from python-olm) (1.14.3)
Requirement already satisfied: future in ./lib/python3.7/site-packages (from python-olm) (0.18.2)
Requirement already satisfied: pycparser in ./lib/python3.7/site-packages (from cffi>=1.0.0->python-olm) (2.20)
Installing collected packages: python-olm
Running setup.py install for python-olm ... error
ERROR: Complete output from command /home/l2g/Development/home-assistant.core/bin/python3 -u -c 'import setuptools, tokenize;__file__='"'"'/tmp/pip-install-n3e2d485/python-olm/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-99nxg11e/install-record.txt --single-version-externally-managed --compile --install-headers /home/l2g/Development/home-assistant.core/include/site/python3.7/python-olm:
ERROR: make: *** No rule to make target '../include/olm/olm.h', needed by 'include/olm/olm.h'. Stop.
running install
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.7
creating build/lib.linux-x86_64-3.7/olm
copying olm/utility.py -> build/lib.linux-x86_64-3.7/olm
copying olm/session.py -> build/lib.linux-x86_64-3.7/olm
copying olm/sas.py -> build/lib.linux-x86_64-3.7/olm
copying olm/pk.py -> build/lib.linux-x86_64-3.7/olm
copying olm/group_session.py -> build/lib.linux-x86_64-3.7/olm
copying olm/account.py -> build/lib.linux-x86_64-3.7/olm
copying olm/_finalize.py -> build/lib.linux-x86_64-3.7/olm
copying olm/_compat.py -> build/lib.linux-x86_64-3.7/olm
copying olm/__version__.py -> build/lib.linux-x86_64-3.7/olm
copying olm/__init__.py -> build/lib.linux-x86_64-3.7/olm
running build_ext
generating cffi module 'build/temp.linux-x86_64-3.7/_libolm.c'
creating build/temp.linux-x86_64-3.7
building '_libolm' extension
creating build/temp.linux-x86_64-3.7/build
creating build/temp.linux-x86_64-3.7/build/temp.linux-x86_64-3.7
gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/home/l2g/Development/home-assistant.core/include -I/usr/include/python3.7m -c build/temp.linux-x86_64-3.7/_libolm.c -o build/temp.linux-x86_64-3.7/build/temp.linux-x86_64-3.7/_libolm.o -I../include
build/temp.linux-x86_64-3.7/_libolm.c:570:18: fatal error: olm/olm.h: No such file or directory
570 | #include <olm/olm.h>
| ^~~~~~~~~~~
compilation terminated.
error: command 'gcc' failed with exit status 1
----------------------------------------
ERROR: Command "/home/l2g/Development/home-assistant.core/bin/python3 -u -c 'import setuptools, tokenize;__file__='"'"'/tmp/pip-install-n3e2d485/python-olm/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-99nxg11e/install-record.txt --single-version-externally-managed --compile --install-headers /home/l2g/Development/home-assistant.core/include/site/python3.7/python-olm" failed with error code 1 in /tmp/pip-install-n3e2d485/python-olm/ I think this is a very large undertaking that requires the rebirth of their If you find any working E2E Python examples of other people acomplishing what you're asking, please let me know. |
Hello @caronc ! Thanks for the idea review and I'm glad that you liked it. I see that it might not be easy task at all. It's interesting that the official SDK is not that well maintained. It is also interesting that the encryption is not properly implemented as of today end-to-end encrypted rooms are default in Matrix world. Official SDK readme says like this:
So would using this help? Atleast their documentation says that "transparent end-to-end encryption (EE2E)" is actually implemented. I'm not sure if apprises Matrix notifications are implemented using basic REST client or are you using the official SDK but if you would change to use matrix-nio, this would indeed require some work to change the plugin use this client instead. |
I also noticed that mautrix-python has a support for EE2E. |
Thank you, I'll look into this |
Support E2EE support would be extremely practical, since the E2EE part is the real pain here when setting up notifications for matrix. I looked into doing this with the matrix-nio library that @uuksu mentioned and found this example to work along: https://github.com/poljar/matrix-nio/blob/20ac350d015b9fb1363482661a1d9d26e28914c1/examples/manual_encrypted_verify.py All that is needed is installing the olm dependency with:
or
and adding the matrix-nio dependency with E2EE support: The dependency for olm is somewhat unfortunate, but perhaps this can be made optional, similarly to matrix-nio. I am not very experienced with tooling and packaging in python. I varied and shortened the example to something that might do what apprise needs. I had look at the current setup and was not quite sure how to implement (which seems to be sync) with this asynchronous solution properly. I am generally not very firm with asynchronicity in python, so the process just keeps running and does not terminate as well yet. Here is my attempt, though:
I'd love to see this feature added and happy to help and add tests to the best of my ability |
I'm not a matrix spokesperson or professional dev, but hobby enthusiast, but based on what I learned trying to implement e2ee for a matrix bot the following is at least part of the trouble: The difficult part with supporting matrix e2ee in a stateless setting such as apprise's is that matrix clients like the nio library would prefer, or even require, to store some data:
That is due to the asymmetric encryption used: apprise must first download ("sync") the other matrix room participants list and get their public keys in order to then encrypt the message with said keys and send it. A problem is, depending on the account size (i.e. complexity and number of rooms the apprise account is in), doing an "initial sync" can take quite a couple minutes. One way to improve this situation is being worked on: Sliding Sync will only download parts of the account which the client requests. There might still remain a delay issue with keys however, I'm not quite sure. |
I toyed with a persistent storage module of Apprise so that it could store more advanced things (such as long cyphers and other metadata outside of what fits in a (Apprise) URL, but didn't get much time to expand it to the point i was proud enough to share it with others. The idea was to provide a sandboxed location related to each service that needed it. Seems like this is a use case. For now, the solution would still be to store it in memory (for life of program call). You still also need to be able to load your own encryption as well. The keys are to long to put in the Apprise URL. You'd have to pass a local file on the URL to read it's cfg from i think. Anyway, if you guys have ideas on how to tackle this, by all means, i welcome pull requests. |
Author of sliding sync here: yes you would be able to use sliding sync for this use case, however sliding sync is a long term project, and won't help you right now. There's a few critical things you need to do when you send an E2EE message, which you can see if you look at the Network tab when you send an E2EE message in a web client like Element:
In other words, in order to send an E2EE message "statelessly", you need to fetch:
To get the list of joined members at a single point in time, you can just hit |
If you decide to go with a state store of Apprise, feel free to copy any code from my repo if it helps. I'm also using the nio lib in my Matrix E2E webhook implementation, it's super easy: https://github.com/immanuelfodor/matrix-encrypted-webhooks/blob/main/src/E2EEClient.py The only problem I envision is that the store nio creates is an SQLite DB file. This is very problematic when running an application over NFS as SQLite depends on Posix file locking, and NFS is not, so the DB gets corrupted after a few writes. NFS is the most common RWX volume type among homelabbers when a shared storage is attached to multiple Kubernetes nodes so that newly scheduled pods can access it from any node. Since Apprise is used in a wide variety of tools, those tools that depend on it would be not usable over NFS anymore. Please consider this when planning an implementation. The store must be represented by plain files or a DB over TCP/IP like MySQL/MariaDB/PostgreSQL. |
💡 The Idea
At the moment it seems that notifications sent to Matrix are actually unencrypted. This is pretty confusing as even when room is set to be end-to-end encrypted all notification are handled as unencrypted messages and messages have this nasty warning sign next to them in Element:
If I've understood correctly, this would require implementing end-to-end encryption flow to Apprises Matrix plugin. This includes acquiring keys from other devices (user clients in Matrix terminology) and then encrypting messages.
Implementation guide here: https://matrix.org/docs/guides/end-to-end-encryption-implementation-guide
I'm not sure if there is something that could be blocking implementing this. If notifications were end-to-end encrypted it would make Matrix a superior place to receive notifications when true privacy is needed!
The text was updated successfully, but these errors were encountered: