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

Discord fails to load unless microG is disabled #759

Closed
ghost opened this issue Apr 18, 2019 · 26 comments
Closed

Discord fails to load unless microG is disabled #759

ghost opened this issue Apr 18, 2019 · 26 comments

Comments

@ghost
Copy link

ghost commented Apr 18, 2019

logcat.txt

Just fails to connect. Will connect successfully, albeit with a "Google Play Services is nrequired" message, with microG disabled.

@incognico
Copy link

incognico commented Apr 22, 2019

Discord works fine for me, even push messages do work. I'm opted in to the beta tho (Discord Public Test Build https://play.google.com/apps/testing/com.discord or from apkmirror).

@ghost
Copy link
Author

ghost commented Apr 22, 2019

Oh, ok.

@mar-v-in
Copy link
Member

This seems to be a regression caused by 7259265

@ghost
Copy link
Author

ghost commented Apr 24, 2019

So wait.... adding functionality made Discord not work? That's weird.

@Vavun
Copy link
Contributor

Vavun commented Apr 24, 2019

I think we need to tag @voidstarstar here,
Some poeple reported same issue on 4pda community

@voidstarstar
Copy link
Contributor

Thanks for letting me know.

I suspect this is due to the default SSLSocketFactory and SSLServerSocketFactory not being set to match conscrypt, but I'll have to test this to be sure.

@mar-v-in
Would it be acceptable to copy the code from MGit as described in the original issue #504 (comment)? This code was committed over a year ago by @kb-1000 and they actually joined the discussion in #635.

Regarding licenses, MGit is GPL-3, so explicit permission from the original author may be needed to use this code without changing the microG license. The code is pretty straight forward, so I'm not sure if there's any other way to go about it.

@mar-v-in
Copy link
Member

mar-v-in commented Apr 24, 2019

I already tried if applying these additional code helps, but it doesn't.

Also I checked the details of the code, some of it is valid and covers the sidecase when the SSLContext was used before insertProvider() was invoked. It shouldn't cause any issues without that code other than degraded security.

The reflection bit is completely obsolete though, as calling Security.insertProviderAt() will cause increase of Security.getVersion() which in turn will cause the cache in defaultSocketFactory and defaultServerSocketFactory (which is what the reflection code sets) to be abandoned anyway (see AOSP source code)

@voidstarstar
Copy link
Contributor

Oh interesting find. Did they diverge from the openjdk implementation, but not update the Javadoc?

Returns the default SSL socket factory.

The first time this method is called, the security property "ssl.SocketFactory.provider" is examined. If it is non-null, a class by that name is loaded and instantiated. If that is successful and the object is an instance of SSLSocketFactory, it is made the default SSL socket factory.

Otherwise, this method returns SSLContext.getDefault().getSocketFactory(). If that call fails, an inoperative factory is returned.

I just tried and can confirm that the vanilla v0.2.6.13280 seems to connect just fine. Maybe conscrypt disabled some cyphers that the Discord servers require?

@ale5000-git
Copy link
Member

From the logcat:

04-18 05:41:03.845 23304 23304 D GmsDynamiteLoaderImpl: unimplemented Method: getModuleVersion for providerinstaller
04-18 05:41:03.845 23304 23304 I DynamiteModule: Considering local module providerinstaller:0 and remote module providerinstaller:0
04-18 05:41:03.845 23304 23304 W ProviderInstaller: Failed to load providerinstaller module: No acceptable module found. Local version is 0 and remote version is 0.
04-18 05:41:03.852 23304 23304 V NativeCrypto: Registering org/conscrypt/NativeCrypto's 284 native methods...
04-18 05:41:03.859 23304 23343 W ContextImpl: Failed to ensure /data/user/0/com.google.android.gms/shared_prefs: mkdir failed: EACCES (Permission denied)

May not fix the problem but maybe implementing the method getModuleVersion and creating the folder /data/user/0/com.google.android.gms/shared_prefs may allow to go ahead a bit.

@mar-v-in
Copy link
Member

  • If there is no dynamite module, the client library will fallback to their internal implementation. Dynamite modules allow the GmsCore to replace parts from the client library.
  • The permission denied is intended (and won't be fixed by creating a folder): This happens when the client library creates a remote context object as GmsCore. As remote context are not restricted in any way, they don't get access to the private data (including preferences) of GmsCore.

@moso
Copy link

moso commented Apr 26, 2019

I'd like to join in, although with a bit less technical information compared to what's been posted so far.

My experiences with Discord on a Pixel 3 with microG are the following:

  • Discord registers fine with GCM/FCM
  • One can log in, even when the recaptcha comes up which is solvable in a browser
  • We get an FCM token as seen in Discord settings -> Debug

Something goes wrong from here. Log from debug:

[GatewaySocket] Discovering gateway url.
[GatewaySocket] Discovered gateway url: wss://gateway.discord.gg
[GatewaySocket] Connect to wss://gateway.discord.gg, encoding: json, version 6.
[GatewaySocket] Discovery failed, retrying in 10000ms.
[GatewaySocket] Reset dirty, with code 0, at sequence 0. Reason: 'Gateway discovery failed.'.
[GatewaySocket] Closed cleanly: false, with code 0, for reason: 'Connection timed out after 20001ms, did not  receive hello in time.'.

Also, when the app tries to fetch /@me/devices from the Discord API, it doesn't return anything, thus our username is either empty or set to "EMPTY_USERNAME". This results in the app trying to fetch /user/0/profile which returns a 404, and we get a gateway discovery error.

The odd thing is though: We still get notifications from messages. There are no servers to interact with, no account info, but notifications through FCM works. So that's positive. It's just the rest of the app that's missing.

I tried filing this as a bug with Discord but their answer was straight up "if you hack around with Play Services then you're on your own". I then tried reasoning with them asking why their app relied on Play Services to be present, as getting data from an API and the lack of Play Services shouldn't conflict with pure, raw Android with no Play Services present. No answer.

@BeeeWall
Copy link
Contributor

BeeeWall commented May 2, 2019

As a workaround, I'm using the app Shelter to run Discord in a work profile that has microG disabled. Not sure if push notifications with it will work or not though.

@moso
Copy link

moso commented May 2, 2019

Initially I deleted the following comment but after testing for 4 days, I can somewhat confirm this.

A possible workaround (or even solution) might be to use Magisk Hide to hide SU from Discord. However, Discord Testers confirmed that root has nothing to do with the app. But adding Discord to the list, both notifications and chat works flawlessly. I even confirmed it by removing Discord from the Magisk Hide list again, and the problems were back. Re-adding it to Magisk Hide solved it for me.

What Magisk Hide does versus what Discord API does with FCM still boggles me a bit. Maybe @mar-v-in can fill us in.

@BeeeWall
Copy link
Contributor

BeeeWall commented May 2, 2019

Oh wow, you're right. Are you using microG with a Magisk module such as NanoDroid? My guess is that using Magisk Hide hides that module from Discord as well as root. As noted in the OP, disabling microG makes it work. So if using Magisk Hide hides microG from Discord, that could explain why it works. Did you log in originally without Magisk Hide on and enable it after, or enable it and then log in?

@moso
Copy link

moso commented May 2, 2019

@BeeeWall Yep, I had to resort to using NanoDroid. Otherwise my Pixel 3 wouldn't boot. And maybe you're right in what causes it to work with Magisk Hide. I just noticed that it worked after hiding root from Discord. And yes, I tested it by removing hide again, and Discord stopped working. What I noticed this time was that it asked the API for the correct user-ID, but it still failed.

@voidstarstar
Copy link
Contributor

Have any other apps had issues with the ProviderInstaller? Perhaps it's a websocket compatibility issue? I also wonder if Discord is doing something atypical like verifying if the provider conscrypt uses is the same version as the up to date Play Store version. Typically an app would simply verify that the Play Store is up to date, so this is unlikely.

For what it's worth, it does not appear that Discord is using any old version of SSL/TLS, bad ciphers, etc., so I don't think it's an intended failure to connect.

I tried filing this as a bug with Discord but their answer was straight up "if you hack around with Play Services then you're on your own". I then tried reasoning with them asking why their app relied on Play Services to be present, as getting data from an API and the lack of Play Services shouldn't conflict with pure, raw Android with no Play Services present. No answer.

This is a bug with microG, not Discord, so please try to avoid bothering their devs over this issue. It would definitely be nice to better understand what their app is doing, but it's understandable that they don't want to support microG. It's the responsibility of microG to be compatible with Discord, not the other way around. They rely on Play Services for, among other things, push notifications, which is perfectly reasonable.

@Nanolx
Copy link
Contributor

Nanolx commented May 11, 2019

I may add that using Magisk Hide does not solve the issue for most. Yes, for whatever reason for some it fixes it (though no one knows why), but for most (including me), it doesn't.

I have not yet run across other apps causing regressions (I only tested discord because others reported the issue), though except some Nintendo Games all my apps are Open Source apps that properly work without Play Services aswell, so my setup isn't really of help.

@BeeeWall
Copy link
Contributor

Magisk Hide stopped helping for me recently. Not sure if it was a Discord update, a Magisk one, or what (I updated both around the same time). Currently I'm using Shelter to run it in a work profile with microG frozen.

@ErikSteiner
Copy link

MagiskHide is working for me, I just downloaded the App from Play Store 2 minutes ago. I logged in, solved the capture in browser and then I logged in. When Discord tried to connect for ages, I closed the App and added it to MagiskHide. When I opened Discord after that, it connected immediately. Maybe it is not a good idea to add it to MagiskHide at the very beginning?

@moso
Copy link

moso commented May 15, 2019

While the Magisk Hide method is still working for me, a more sustainable solution is probably to follow @BeeeWall's example, and run Shelter to freeze microG in a work profile. Magisk sometimes just stop working without warning on my phone. Not just this phone; this also happened on my OnePlus 3T. So to have something a bit more reliable than a root that only stays running 90% of the time (again, this is my experience), is a priority.

Until we solve the actual cause, that is.

@ghost
Copy link
Author

ghost commented May 15, 2019

05-15 06:58:33.669 3899 4272 I Discord : [GatewaySocket] Reset dirty, with code 4000, at sequence 0. Reason: 'Disconnect requested by client'.

@BeeeWall
Copy link
Contributor

BeeeWall commented May 15, 2019

Well I'm both in the Discord alpha and on the Magisk Canary channel, so if something is broken it might not've reached stable or even beta yet. But hopefully it's just a me bug and it works for others. I wonder if maybe one of the canary Magisk updates changed MagiskHide at all? May look at the commit history to check.
Strangely, Discord actually partially works without MagiskHide/Shelter/etc. It's never fully loads ex. roles and nicknames, but I can load messages (although I have to close and reopen the app to see latest ones), I can send them (it shows as stuck on sending but again restarting the app shows it actually sends), etc. It seems it may be limited to channels I have seen back when it was working though. I wonder why some things work and some don't.
An unfortunate thing with the Shelter method is that when you receive a push notification, you have to go to the homescreen, open the sheltered version, and navigate to the right channel, because push only works for the unsheltered version. Better than it not working at all though.
Basically, if the MagiskHide method works for you, it's probably best to use it. If not, Shelter works but is a little more complicated to use sometimes. And if for some reason you can't use Shelter, Discord may still possibly work a little bit.

@Nanolx
Copy link
Contributor

Nanolx commented May 27, 2019

Fixed with commit 51e5f77 by mar-v-in

Successfully tested it with latest Discord release (no Magisk Hide or whatever needed).

Thanks.

@ghost
Copy link
Author

ghost commented May 27, 2019

👏

@voidstarstar
Copy link
Contributor

Good work! The special exception for Discord seems like a good compromise.

It should just be noted that this is a workaround where Discord isn't going to benefit from any security updates from conscrypt. Eventually Discord might disable older TLS versions on their server which could leave the app not working on older versions of Android.

@ale5000-git
Copy link
Member

Problem is fixed and new version is released.
If there is any other problem, please report it.

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

No branches or pull requests

9 participants