Skip to content
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

Unifiedpush #152

Merged
merged 24 commits into from
Nov 2, 2023
Merged

Unifiedpush #152

merged 24 commits into from
Nov 2, 2023

Conversation

p1gp1g
Copy link
Member

@p1gp1g p1gp1g commented Dec 1, 2022

This pull request add UnifiedPush support to Molly. (Issue #88)

There will still be some changes and some elements are still missing, but it can now start to be reviewed and tested.

It requires a MollySocket server running (still in alpha) on a server.

The MollySocket build can be found here: https://github.com/MollySocket/mollysocket/releases
And this fork (Molly with unifiedpush) build here: https://github.com/mollyim/mollyim-insider-android/releases

How it works ?

  • When UnifiedPush is enabled, Molly (android) creates a linked device without encryption keys then sends the linked device's credentials to MollySocket (*).
  • MollySocket connects to the Signal Server websocket with the linked device's credentials. Every time MollySocket receives a(n encrypted) event, it notifies Molly via UnifiedPush and Molly fetch the new messages (*).

* Modulo the configuration

About the configuration

Old and removed strategy conf * There are 2 different fetch strategies: * REST: Every time MollySocket receives a(n encrypted) data : it notifies Molly via UnifiedPush and Molly fetch using the rest strategy (that's a built-in strategy) * Websocket: Every time MollySocket receives a(n encrypted) data : it notifies Molly via UnifiedPush if it hasn't notified the last 5 seconds. Then Molly open the websocket for 20secs. This strategy avoid to reach some rate limit for some public provider such as https://ntfy.sh but may increase a little bit the battery drain.
  • If your MollySocket server can't be reached on the Internet (via HTTPS), or you don't want to: you can enable the Air Gaped mode. You will have to register the linked device manually. The parameters can be copied in the settings menu

Tests

It needs some tests to know which strategy is better for reliability and battery !
Your feedback is welcome to compare the efficiency of the different strategy: MollySocket/mollysocket#1.

About security

Relative to Signal security

MollySocket receives the credentials for a linked device and does not receive any encryption key. Which means:

  • Someone with access to MollySocket database can't change the identity key, to impersonate users. See setKeys.
  • Someone with access to MollySocket database may be able to use the credentials of linked devices to spam the Signal server and hit the rate limits. I haven't checked if this would temporarily block the account or just the linked device. (Availability risk)
  • Someone with access to MollySocket database may be able to change some account field in a destructive way. For instance changing the account Name to something random. The cleartext will be random since these field are encrypted and require encryption keys to be properly encrypted.

Todo

  • Use encrypted store instead of shared prefs
  • Alert users in some edge cases
  • Ensure FCM is started if needed, when UnifiedPush is no more available & FCM is
  • Use signal executor with fixed pools of workers instead of Threads
  • Use EventBus/RxJava instead of local broadcasts for config changes

@p1gp1g p1gp1g force-pushed the unifiedpush branch 3 times, most recently from 5af2057 to fcfac64 Compare December 8, 2022 19:12
@genofire
Copy link

I believe to find a bug: does it reregister with the new strategy, if you change it in the UI ?

@p1gp1g
Copy link
Member Author

p1gp1g commented Dec 22, 2022

I believe to find a bug: does it reregister with the new strategy, if you change it in the UI ?

Yes it does, since the server does not act the same way depending on the strategy

@dinosmm
Copy link
Collaborator

dinosmm commented Dec 22, 2022

If merged as is, would this work with a Nextcloud NextPush UP server? Or would it only work with a MollySocket server?

@genofire
Copy link

@dinosmm the mollysocket-server is needed to get the notification from signal per websocket to any UnifiedPush provider.

So you need both.
For testing i am running an mollysocket under https://mollysocket.sum7.eu if you want to test it.

@tuxayo
Copy link

tuxayo commented Dec 26, 2022

How it works ?
When UnifiedPush is enabled, Molly (android) creates a linked device without encryption keys then sends the linked device's credentials to MollySocket ().
MollySocket connects to the Signal Server websocket with the linked device's credentials. Every time MollySocket receives a(n encrypted) event, it notifies Molly via UnifiedPush and Molly fetch the new messages (
).

Is this a trick to avoid needing any change done to the Signal Server?

@p1gp1g
Copy link
Member Author

p1gp1g commented Dec 26, 2022

Is this a trick to avoid needing any change done to the Signal Server?

Indeed, if the signal server allowed pushing to arbitrary endpoints (= push server addresses), then mollysocket would not be necessary.

@p1gp1g
Copy link
Member Author

p1gp1g commented Dec 26, 2022

I have fixed the main issue with the unattended unregistration + Lint

@p1gp1g
Copy link
Member Author

p1gp1g commented Dec 27, 2022

Except the alerts for the edge cases, I think this PR is now ready :)

@SlugFiller
Copy link
Contributor

What are the security properties of MollySocket? Do you have to host your own? What security risks does using a 3rd party MollySocket server entail? Does it require a valid DNS entry?

@genofire
Copy link

genofire commented Dec 30, 2022

@SlugFiller you could run mollysocket without make it public as an Webservice ( and DNS record). The Unified Push Service has to be Public. MollySocket just has to be able, to reach the Unified Push Service and the Signal Server fore there Websocket. That is called Airgapped in the Documentation:
https://github.com/MollySocket/mollysocket#android

I am not sure over the security risk. @p1gp1g should answer.
I believe there is just an risk that someelse know that you are notified from signal and which Unified Push Service (with the ID) you use.
The messages itself are still just encrypted on your device. And I do not believe that no mollysocked or Unified Push hoster get any information about the sender of the message.

@p1gp1g
Copy link
Member Author

p1gp1g commented Dec 30, 2022

What are the security properties of MollySocket? Do you have to host your own? What security risks does using a 3rd party MollySocket server entail?

Relative to Signal: MollySocket only receives credentials from a linked device.
As long as the Signal protocol is not broken (:sweat_smile:), the only remaining risks would be:

  • If the linked devices could change the identity keys, then someone with access to mollysocket could change them, and impersonate the users (note that all contacts would be notified by a key change). Fortunately, linked devices are not allowed to change these keys. See setKeys.
  • Someone with access to mollysocket could use the credentials of linked devices to spam the Signal server and hit the rate limits. I haven't checked if this would temporarily block the account or just the linked device. (Availability risk)

[Edit: And of course, mollysocket knows when you receive encrypted data]

Does it require a valid DNS entry?

If you want the MollySocket endpoint to be accessible from the Internet: yes
else you can use the air gaped mode: then you have to register the linked device on mollysocket with a command line

@SlugFiller
Copy link
Contributor

@p1gp1g Are the linked device credentials insufficient to send/read messages on the user's behalf? Can the credentials be reduced to something sufficient to detect a message, but insufficient to decrypt it?

What about sending messages to the primary, like storage sync, which could read and edit contacts and groups?

@p1gp1g
Copy link
Member Author

p1gp1g commented Dec 30, 2022

@p1gp1g Are the linked device credentials insufficient to send/read messages on the user's behalf? Can the credentials be reduced to something sufficient to detect a message, but insufficient to decrypt it?

What about sending messages to the primary, like storage sync, which could read and edit contacts and groups?

You are right, I need to list the rights given to linked device without encryption keys. Except for the identity keys [1], you should consider giving the same trust to mollysocket than you give to signal server [2]. That is why it is better to self host it.

[1] Signal Server is technically able to change the identity key. I don't know how Signal client would react. In case of signal server compromise, your contact getting the client-side alert about identity key change is the last protection.
[2] Every sensitive action require encryption keys, if not, that should be considered as an issue since you giving trust to signal server.

Edit: I don't know if it is useful to list what can be edited. This edition is only destructive since you can't encrypt arbitrary data without the keypair.

@p1gp1g
Copy link
Member Author

p1gp1g commented Dec 30, 2022

Actually, since everything is encrypted with the same protocol, the only risk is a destructive modification of some data. For instance, I can send junk as my Name but it won't be decrypted by signal clients

@p1gp1g
Copy link
Member Author

p1gp1g commented Dec 30, 2022

Thanks @SlugFiller : I have added a note about security on the first message and on mollysocket repository. If you have any other thing in mind, please ask :)

@valldrac
Copy link
Member

valldrac commented Jan 1, 2023

Just released a new testing APK:

https://github.com/mollyim/mollyim-insider-android/releases/tag/v6.6.3-1.rev2%2Bunifiedpush

I rebased your changes to latest Molly v6.6.3-1. I had to fixed a couple of minor conflicts.

@p1gp1g p1gp1g force-pushed the unifiedpush branch 3 times, most recently from 2c23082 to d821abf Compare January 29, 2023 15:55
@Neon-44
Copy link

Neon-44 commented Feb 22, 2023

this looks really promising, am really hyped for it.

this will be really cool for us trying to de-google.

subscribed to the PR

@ArtikusHG
Copy link

I am currently testing this and I'd like to point out that while it works fine, Molly still stays in the background as an active app, even though it doesn't need to. This should be disabled if the UnifiedPush notification method is used, as the whole point of this use case is not having the app constantly stay in the background.

Side note, specifying a default MollySocket server would be great and less confusing to new users.

Great work by the way! Really appreciate it :p

@p1gp1g
Copy link
Member Author

p1gp1g commented Feb 22, 2023

Molly still stays in the background as an active app, even though it doesn't need to. This should be disabled if the UnifiedPush notification method is used, as the whole point of this use case is not having the app constantly stay in the background.

That's because the websocket strategy needs the service being running, but the connection is active only when a message arrives. Even if the foreground service is active, it consumes less than the signal service with the continuous websocket (*) to signal server :)

The REST strategy removes that foreground service but mollysocket becomes more verbose then, so you must be sure your unifiedpush distributor won't ban you (eg. rate limit)

Great work by the way! Really appreciate it :p

Thanks :)

* Actually, signal uses 2 websockets with the foreground service but that is off topic :)

@ArtikusHG
Copy link

Switching to REST worked, thanks! I was specifically looking to reduce the amount of background processes on my device, ideally, to only have ntfy running (right now there's Forkgram still left, hopefully someone works on UnifiedPush, maybe I'll do it myself one day), and this PR really helps! Hopefully it gets merged soon.

Also, as for rate limiting, if my migration from WebSocket background notifications to UnifiedPush goes well, I will probably just host my own server, so yeah. Thanks again for the PR, looking forward to the merge!

@p1gp1g
Copy link
Member Author

p1gp1g commented Feb 24, 2023

Just be careful, you may get rate limited very fast with REST strategy and a public ntfy server

@Darin755
Copy link

What's holding up this PR? Is there something I can help with?

@p1gp1g
Copy link
Member Author

p1gp1g commented Oct 13, 2023

We are releasing a new official build of Molly with UnifiedPush support. A first build is available here : https://github.com/mollyim/mollyim-android-unifiedpush/releases

We will communicate about this soon :)

@d4f5409d
Copy link

d4f5409d commented Nov 2, 2023

We are releasing a new official build of Molly with UnifiedPush support. A first build is available here : https://github.com/mollyim/mollyim-android-unifiedpush/releases

We will communicate about this soon :)

How can we activate it? I don't see it anywhere in the settings.

@valldrac valldrac changed the base branch from main to unifiedpush November 2, 2023 23:34
@valldrac
Copy link
Member

valldrac commented Nov 2, 2023

I'm happy to share some good news today! UnifiedPush support has finally landed in Molly.

We've put a lot of effort into making this happen. Starting from now, UnifiedPush support is officially available in a separate app, that you can download from the GitHub Releases page here or Molly's F-droid FOSS repository here.

I'm closing this pull-request now, but please note these changes have been already merged into the new repo: https://github.com/mollyim/mollyim-android-unifiedpush.

It wouldn't have been possible without the incredible contributions and support from all of you. So, a massive thanks to everyone involved in making UnifiedPush a reality in Molly.

@valldrac valldrac merged commit cfa7d32 into mollyim:unifiedpush Nov 2, 2023
2 checks passed
@networkException
Copy link

Is there an upgrade path from the current app to the unified push version? If not, will there be in the future? Or does it make sense to just migrate now

@p1gp1g
Copy link
Member Author

p1gp1g commented Nov 3, 2023

You can backup your data, install the other build and restore your data

@ghost
Copy link

ghost commented Nov 3, 2023

Will this be available for accrescent users?

@valldrac
Copy link
Member

valldrac commented Nov 4, 2023

Will this be available for accrescent users?

Not for now. It implies a significant extra workload. We'll do it when the process improves, either on our end or through Accrescent's efforts.

UnifiedPush users can rely on the in-app updater to update the app.

@seffs
Copy link

seffs commented Nov 13, 2023

Hi @valldrac @p1gp1g and everyone else involved on this release,

Hats off to you. I can confirm that it is working as intended in my phone. My phone's battery cannot thank you enough.
I am curious about what configuration we need once UP is active. IIRC, for connections without FCM Signal/Molly need a persistent notification that allows the app to work in the background.

1) Is this persistent notification still necessary for UP?
2) Can I turn on battery optimization for Molly in this case?

I was playing on and off with these settings and somehow Molly managed to waste 20% battery life. Also when disabling the persistent notification, sometimes new messages don't show up unless I open the app again. Is there something I am missing here? What would be the ideal settings for UP?

I figured it out. Needed the mollysocket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.