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

Add user-install microG User Services #2188

Merged
merged 16 commits into from
Sep 28, 2024
Merged

Conversation

p1gp1g
Copy link
Contributor

@p1gp1g p1gp1g commented Feb 19, 2024

Following discussion on #2183 (which may be closed ? Superseded by this one)

@mar-v-in @ale5000-git

I have tested, and org.microg.gms can't be installed on a system with com.google.android.gms (Google or microG) because of duplicate permission.

I have used the dimension 'target' for the user flavor, I think that's the one to use.

@ale5000-git
Copy link
Member

@p1gp1g
If I'm not wrong, permissions can be defined more than one time if both apps are signed with the same signature.

@ale5000-git
Copy link
Member

Now it fails build:

/home/runner/work/GmsCore/GmsCore/play-services-core/src/main/AndroidManifest.xml:137:9-36 Error:

	Attribute application@label at AndroidManifest.xml:137:9-36 requires a placeholder substitution but no value for <appLabel> is provided.
/home/runner/work/GmsCore/GmsCore/play-services-core/src/huawei/AndroidManifest.xml Error:
	Validation failed, exiting
> Task :play-services-core:processHmsHuaweiDebugMainManifest FAILED

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 20, 2024

I've not tested locally, but it should build now. I'll rebase to fix the commit into the previous one later.


@p1gp1g If I'm not wrong, permissions can be defined more than one time if both apps are signed with the same signature.

IIRC signature spoofing works only for system app, so microG (system) should have a different signature. I think we should test this case.


A few things should be done on the UI for the user services:

  • a dialog on first use, explaining that:
    • this service is experimental (?)
    • microG Services use signature spoofing to work with applications using the google libraries, this build does not use this technique and works only with application which use the microG libraries replacement.
    • Help is welcome to word this :)
  • Remove the signature spoofing check for the user services
  • Maybe remove some other things ?

@mar-v-in
Copy link
Member

mar-v-in commented Feb 20, 2024

microG Services can be installed as a user / non-system app already. (If that's not possible on GrapheneOS that might be a GrapheneOS specific issue and would be interesting to analyze that.) As a matter of fact, I personally run microG as a user app myself (using my homebrowed OS that's just very few modifications on top of AOSP).

Many systems would not allow signature spoofing when installing microG as a user app. While signature spoofing might be restricted to system apps on systems that come with microG, that doesn't mean it needs to be. DivestOS for example supports signature spoofing for microG running as a user app.

Signature spoofing does not have an impact on any (security) feature of the OS that are signature specific (like signature shared permission declarations). Signature spoofing only affects apps that ask the OS for the signing certificate of an app - which essentially is only the play services client library, because use of that OS feature is discouraged by Google for being insecure as a security mechanism (it's possible to run race attacks against it) and unsuitable for anything else.

Some OS include modified or resigned versions of microG Services. Those obviously have a different signature and can't be upgraded from the original microG package. Otherwise, I would nornally expect both variants to be signed using the same signing key, so that it's easy for users to verify.

To prevent users from installing both, we can and probably should just display appropriate messages when the user does so. Reworking the self-check has been on my list for some time already, so this could become part of it.

Given what I wrote I think the branding as "microG User Services" is very much misleading. We should come up with another name before publishing this. Something along the lines of "microG Services without Google Play Services compatibility", which would be more descriptive but not a nice name ;)

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 20, 2024

I'll use CGAG for services with id com.google.android.gms and OMG to talk about services with id org.microg.gms.


Many systems would not allow signature spoofing when installing microG as a user app. While signature spoofing might be restricted to system apps on systems that come with microG, that doesn't mean it needs to be. DivestOS for example supports signature spoofing for microG running as a user app.

TIL about DivestOS doing it. Still, you shouldn't be able to install OGM + CGAG because of signature spoofing for the later. Nevertheless, some user without signature spoofing at all may try to install both on their system (which wouldn't work with CGAG). [Edit: OGM and CGAG can be installed on the same system.]

A user installing OMG when CGAG is already installed should not be an issue since CGAG has always the priority.

The main issue is :

  1. If a user install CGAG after OMG, then CGAG will take the priority, and some data may be lost (like things needed in shared pref)
  2. If a user install CGAG or OMG after using an application embedding a -core (like the Corona tracing app - CCTG). Then, CGAG or OMG will take the priority, and some data may be lost (like things needed in shared pref)

Note that the 2nd issue is already there.

So. Maybe we should add a dialog to CGAG:

  • if it has been installed after the system install, that some application may use it instead of internal mechanism and the user may need to login again or something like this (to make it understandable)

To prevent users from installing both, we can and probably should just display appropriate messages when the user does so. Reworking the self-check has been on my list for some time already, so this could become part of it.

It isn't important if both is installed, CGAG takes the priority.

Given what I wrote I think the branding as "microG User Services" is very much misleading. We should come up with another name before publishing this. Something along the lines of "microG Services without Google Play Services compatibility", which would be more descriptive but not a nice name ;)

I know, that's a temporary name :)

microG Minus Services ?

@mar-v-in
Copy link
Member

Still, you shouldn't be able to install OGM + CGAG because of signature spoofing for the later.

Signature spoofing has no impact here.

Signature spoofing does not have an impact on any (security) feature of the OS that are signature specific (like signature shared permission declarations). Signature spoofing only affects apps that ask the OS for the signing certificate of an app

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 20, 2024

Sorry, I missed that point, I've edited the previous comment

@p1gp1g p1gp1g force-pushed the feat/user_services branch 2 times, most recently from d304a7d to af11563 Compare February 23, 2024 11:52
@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 24, 2024

The last commit introduced a function to remember the service used by the application. That way, if I use the embedded core, then the app won't use an external one after OMG/CGAG install. For instance, CCTG won't lose its data.

Also, I adds a check to be sure microG/Play services is legit to reduce risks of malicious app branded as another. It assures the service

  • Has an activity (so it will be listed in the installed app)
  • Has a legit name (Note: This is note a space 0x20 between Google and Play for CGAG)

I think this is important because: if a user doesn't have play services/microG with id com.google.android.gms (big if), a malicious app installed with id com.google.android.gms, branded has another service (a cooking app for instance), may use the FIDO service to get access to some services:
1 When the user wants to do a FIDO authent, a request is send to the FIDO service
2. The malicious app uses the key activation to register to another service (the user think it is a legit login)
3. The malicious app sends the response to a remote server and it displays a screen saying there is an error and to retry
4. Do the user's legit login

PS: I don't think the CI Out Of Memory error is related to this PR, isn't it ? Could it be restarted ?

@ale5000-git
Copy link
Member

@p1gp1g

Quote:

If you use the gradle-android-plugin to build your app, then you can use
BuildConfig.APPLICATION_ID
to retrieve the package name from any scope, incl. a static one.

Isn't this simpler?

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 24, 2024

Instead of the resValue package_id ? I've done that because I don't know if that's possible to use it in the activity's xml.

@ale5000-git
Copy link
Member

ale5000-git commented Feb 24, 2024

Yes, for the microG self check it should be the simplest way (it also avoid passing context), for other cases I don't know; I don't have time to try currently.

@mar-v-in
Copy link
Member

In AndroidManifest.xml you can use ${applicationId} to get the current application id, never tried if that works for other resource files

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 24, 2024

Yes, for the microG self check it should be the simplest way (it also avoid passing context), for other cases I don't know; I don't have time to try currently.

You mean the check in function MultiConnectionKeeper.getTargetPackageWithoutPref ? This is intended to be a library to service check (eg. Browser requests microG)

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 25, 2024

The packageId must be shared with a resValue if it used in resource files (eg. https://stackoverflow.com/questions/57074999/get-application-id-in-xml-dynamically)

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 25, 2024

I have renamed the services microG Minus Services, this will be less confusing. Feel free to change the name

I have also added a dialog on first run to inform the user that this flavor is only compatible with microG libraries, I hope it will reduce users misunderstanding.

@ArchangeGabriel
Copy link
Contributor

(JFTR, since it was discussed earlier, there is now a major ROM allowing signature spoofing as user app: https://review.lineageos.org/c/LineageOS/android_frameworks_base/+/383573)

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 25, 2024

@ArchangeGabriel

This patch enables signature spoofing when the following conditions are
met:

  • Build is debuggable (userdebug/eng)
  • Package name is com.android.vending or com.google.android.gms
  • Package is signed with microG release keys
  • Fake signature is correct

I'm OK to check the microG signature (or Google Play signature) instead of controlling the application name: https://github.com/microg/GmsCore/pull/2188/files#diff-4fe7d2cf47e0e66eec592e3286e77a70323b66a82f5d43bfe7f903623230525dR77 . I've done that because some other project may want to fork microG/reimplement (I've seen one exists). I can change it if you want

@ale5000-git
Copy link
Member

ale5000-git commented Feb 25, 2024

@ArchangeGabriel
This PR is about an alternative user build of microG; it has a different internal name so it won't be used by apps compiled with Google libraries but only by apps compiled with microG libraries so signatute spoofing isn't needed at all.

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Feb 25, 2024

But this PR introduces 2 things too:

  • the application using the library saves the targetted packageId, so it won't lose data if a service is installed after the first use
  • a check here (posted on the previous post) to ensure another app is not trying to spoof microG. This checks if the app 1. has an activity (to be listed in user app) 2. use a name with Google Play or microG so it won't be branded as something else. This second point could be changed into a signature check.

@ale5000-git
Copy link
Member

Many ROMs ship a custom microG with a different signature, so a signature check isn't a good thing.

@mar-v-in
Copy link
Member

mar-v-in commented Feb 25, 2024

I don't think this name check is really necessary or a good idea. I would prefer if forks of microG would not call themselves microG (to not confuse users), but this reinforces them to actually have microG in their name.

I personally don't think apps taking over the package name is a huge risk as there is a ton of other ways that malware could affect your system if you install apps blindly from untrusted source. But anyway, I'd propose to do at most the following:
For the package name com.google.android.gms, check if it's a system app or signed using Google or microG certificate and if not, introduce some user interaction, asking the user to confirm they want to use services from that app (displaying its name, app icon and maybe even a signature fingerprint). Same for the org.microg.gms package name, except that Google certificate is not accepted for that. The confirmation is obviously to be persisted.
This way, most users will have everything work silently, but those that decide to use a custom microG will have to confirm once (per app) to use it.

Doesn't need to be part of this pull request though.

@ArchangeGabriel
Copy link
Contributor

@ArchangeGabriel This PR is about an alternative user build of microG; it has a different internal name so it won't be used by apps compiled with Google libraries but only by apps compiled with microG libraries so signatute spoofing isn't needed at all.

I know, I was just replying to:

IIRC signature spoofing works only for system app, so microG (system) should have a different signature. I think we should test this case.

from @p1gp1g, even though @mar-v-in already addressed that with:

Many systems would not allow signature spoofing when installing microG as a user app. While signature spoofing might be restricted to system apps on systems that come with microG, that doesn't mean it needs to be. DivestOS for example supports signature spoofing for microG running as a user app.

I was just wanting to point out that allowing signature spoofing as user app just become suddenly much more common. ;)

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Mar 5, 2024

@mar-v-in

I don't think this name check is really necessary or a good idea. I would prefer if forks of microG would not call themselves microG (to not confuse users), but this reinforces them to actually have microG in their name.

I personally don't think apps taking over the package name is a huge risk as there is a ton of other ways that malware could affect your system if you install apps blindly from untrusted source. But anyway, I'd propose to do at most the following: For the package name com.google.android.gms, check if it's a system app or signed using Google or microG certificate and if not, introduce some user interaction, asking the user to confirm they want to use services from that app (displaying its name, app icon and maybe even a signature fingerprint). Same for the org.microg.gms package name, except that Google certificate is not accepted for that. The confirmation is obviously to be persisted. This way, most users will have everything work silently, but those that decide to use a custom microG will have to confirm once (per app) to use it.

I'm OK with that. I've set a signature check, tested with Google Play, if someone can test it with microG.

I've started to look into the user confirmation when the signature doesn't match, it introduces 2 main changes:

  • Setting gmsPackage will be async
  • It needs an activity to open an alert box or something.

I think the user confirmation can fit another PR, but I need to know what's your way to deal with those 2 points :)

@p1gp1g p1gp1g force-pushed the feat/user_services branch 3 times, most recently from 29e662f to 0d911b5 Compare May 20, 2024 16:03
@p1gp1g
Copy link
Contributor Author

p1gp1g commented Jul 5, 2024

Gentle ping for the review @mar-v-in

@mar-v-in
Copy link
Member

Sorry @p1gp1g, I keep moving this to the next milestone. Testing this is a little more involved, so I haven't managed to finish it yet and I don't want to block the release any longer. I'll do my best to finally do this in the next weeks

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Sep 26, 2024

Is it possible to help testing it ? I really wish to use FIDO on my phone 🥲

The only important change is in MultiConnectionKeeper

@mar-v-in
Copy link
Member

My plan was to hit the merge button right after the 0.3.3 release (which is due to happen in the next days), so I will force myself to test it while on master. 0.3.4 is expected to happen in October, so it won't be too long.

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Sep 26, 2024

Great to hear ! Let me know if you need anything (I'm in the matrix room too)

@mar-v-in mar-v-in merged commit 7d740f3 into microg:master Sep 28, 2024
@Vavun
Copy link
Contributor

Vavun commented Sep 28, 2024

Hi
Since this pull request is ready enough to get into the main branch, I'd like to ask a naive question about naming.

Why limited?

At the moment, this microg variant provides relatively identical opportunities for applications.
I am sure that in the future functionality can even become extended, since there is no need to mimic Google services for the operating system and applications.

@p1gp1g
Copy link
Contributor Author

p1gp1g commented Oct 16, 2024

It is limited as it only works with applications using the microg libraries.

Also, some features will not work, because they require system rights. For example the capability to add an application in power-saving whitelist:

private void addPowerSaveTempWhitelistApp(String packageName) {

For this exact feature, we may check if the OS supports GMSCompatibility (like GraphenOS and DivestOS). They add this service to all application using firebase-messaging: https://github.com/GrapheneOS/platform_frameworks_base/blob/4e0f5bc2fab938de0433b19a0c4eb869a60beccd/core/java/com/android/internal/gmscompat/client/GmsCompatClientService.java#L34. It is possible to bind with foreground priority to this service for some seconds, it will achieve the same thing than whitelisting the app

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

Successfully merging this pull request may close these issues.

5 participants