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

Support workspace accounts with basic device management #2296

Draft
wants to merge 16 commits into
base: master
Choose a base branch
from

Conversation

fynngodau
Copy link
Contributor

@fynngodau fynngodau commented Apr 3, 2024

  • Contains request code to Cryptauth enrollment that can satisfy the lockscreen requirement as to resolve the DeviceManagementScreenlockRequired error.
  • For manual testing, it is called when opening the account settings webview from the system account settings.
  • Provides true lockscreen status in query.
  • Automatically send query when all dependencies are met, and logs what is missing otherwise.

To do:

  • Show appropriate error messages when user intervention is needed.

Resolves #896. Resolves #1726. Likely resolves #1838.

Sync keys request is required for Google Workspace-enabled accounts that
mandate a screenlock to be enabled. Note that with this commit, a
working method is provided, but not yet called, and it also doesn't
contain the correct "screenlock enabled" value yet.
For manual testing only. Remove this commit
@fynngodau fynngodau marked this pull request as draft April 3, 2024 23:04
@fynngodau fynngodau changed the title Support workspace accounts Support workspace accounts with basic device management Apr 3, 2024
@aximut
Copy link

aximut commented Apr 4, 2024

Just built your branch on GitHub actions. Using the debug build. Getting the following logcat when clicking on the account settings screen (only relevant parts filtered).
Basically a short spinner appears when clicking and then it returns back to the previous screen. No account settings displayed, and so far could not get the DeviceManagementScreenlockRequired to disappear.

Feels like your code does not get executed (or because the intent returns too fast the deferred part does not get executed), maybe an error on my end.

D AccountSettings: Invoked with com.google.android.gms.accountsettings.SECURITY_SETTINGS and extras Bundle[{account=Supplier{VAL_PARCELABLE@24+228}}]
W ziparchive: Unable to open '/data/app/.../com.google.android.gms-...==/base.dm': No such file or directory
I ActivityTaskManager: Displayed com.google.android.gms/org.microg.gms.accountsettings.ui.MainActivity: +135ms
D GmsHttpFormClient: -- Request --
D GmsHttpFormClient: androidId=...
...
W AccountSettingsWebView: Failed to get weblogin auth.
W AccountSettingsWebView: java.io.IOException: Error=DeviceManagementScreenlockRequired
W AccountSettingsWebView: 	at org.microg.gms.common.HttpFormClient.request(HttpFormClient.java:96)
W AccountSettingsWebView: 	at org.microg.gms.auth.AuthRequest.getResponse(AuthRequest.java:258)
W AccountSettingsWebView: 	at org.microg.gms.auth.AuthManager.requestAuth(AuthManager.java:293)
W AccountSettingsWebView: 	at org.microg.gms.accountsettings.ui.WebViewHelper.openWebWithAccount(WebViewHelper.kt:109)
W AccountSettingsWebView: 	at org.microg.gms.accountsettings.ui.WebViewHelper.access$openWebWithAccount(WebViewHelper.kt:32)
...
D CoreBackPreview: Window{f7e791 u0 Splash Screen com.google.android.gms EXITING}: Setting back callback null

From your code, I expect there should be a debug statement like:

D SyncKeysRequest: -- Request --
...JSON...

@fynngodau
Copy link
Contributor Author

@aximut Unfortunately I haven't been able to find the difference between your builds and my builds. On my end, it is working and outputs (for instance) the request as you expected:

SyncKeysRequest         com.google.android.gms               D  -- Request --
                                                                {"applicationName":"com.google.android.gms","clientVersion":"1.0.0","syncSingleKeyRequests":[{"keyName":"PublicKey","keyHandles":"ZGV2aWNlX2tleQo="}],"clientMetadata":{"invocationReason":"NEW_ACCOUNT"},"clientAppMetadata":[…]}

@aximut
Copy link

aximut commented Apr 6, 2024

Just started further investigation and apparently for me the function returns here:

        if (!it.containsKey(GcmConstants.EXTRA_REGISTRATION_ID)) {
            return null <--
        }

I just rebuilt the main apk (com.google.android.gms, not the com.android.vending one). Is there anything else I need to update? Or might this be a problem with my workspace account?

I added the debug output as in this file and this is the adb log:

D SyncKeysRequest: STARTING GRPC REQUEST PHASE 1
D SyncKeysRequest: STARTING GRPC REQUEST PHASE 2
W MSBackupRestore: Unsupported class loader
W MSBackupRestore: Unsupported class loader
E system_server: Invalid class loader spec: =UnsupportedClassLoaderContext=
E PackageDexUsage: Unsupported context?
W ziparchive: Unable to open '/data/app/~~...==/com.google.android.gms-...==/base.dm': No such file or directory
I ActivityTaskManager: Displayed com.google.android.gms/org.microg.gms.accountsettings.ui.MainActivity: +548ms

Not sure if the class loader issues are related or not.

@fynngodau
Copy link
Contributor Author

@aximut You will need to enable device checkin and Google Cloud Messaging before running the query. I will provide updates to get the functionality in a more use-ready state in the coming days.

@aximut
Copy link

aximut commented Apr 6, 2024

I have device registration and GCM both enabled. For device registration, I can see my Android ID in the microG app. GCM I set to "confirm new apps".

@fynngodau
Copy link
Contributor Author

fynngodau commented Apr 6, 2024

@aximut From the code being called, enabling to "confirm new apps" while querying for an app not yet contained in the database (microG itself) will also yield no result at this moment.

@aximut
Copy link

aximut commented Apr 6, 2024

Thanks! That was it. Now I see the code being fully executed.

D SyncKeysRequest: STARTING GRPC REQUEST PHASE 5
D SyncKeysRequest: STARTING GRPC REQUEST PHASE 6
D SyncKeysRequest: STARTING GRPC REQUEST PHASE 7
D SyncKeysRequest: -- Request --
D SyncKeysRequest: {"applicationName":"com.google.android.gms","clientVersion":"1.0.0","syncSingleKeyRequests":[{"keyName":"PublicKey","keyHandles":"ZGV2aWNlX2tleQo="}],"clientMetadata":{"invocationReason":"NEW_ACCOUNT"},"clientAppMetadata":"..."}

However, once I start a G app afterwards, I still get

D GmsHttpFormClient: -- Request --
D GmsHttpFormClient: androidId=...&app=com.google.android.apps.dynamite&client_sig=...
W GmsAuthManagerSvc: java.io.IOException: Error=DeviceManagementScreenlockRequired

For testing, I commented out all the rest of the web view code though, maybe that's the issue.
Otherwise I'd have to setup the MITM interception again to see more details.

Logs which of the dependencies for setting up enterprise accounts are missing:

* Checkin enabled
* GCM enabled
* microG allowed to use GCM
* Lockscreen enabled
@fynngodau
Copy link
Contributor Author

I've added functionality to automatically send the request if necessary (for instance, when a sync fails with DeviceManagementScreenlockRequired error) and then to re-send the original request if appropriate. If not all dependencies are met, it instead logs what is missing, like this:

GmsAccountErrorResolve  com.google.android.gms  W  User intervention required! You need to ENABLE_GCM, ALLOW_MICROG_GCM, ENABLE_LOCKSCREEN.

ALLOW_MICROG_GCM means what we discussed above (it fails if a user disabled GCM for microG specifically, or requested to manually allow new apps).

The next step will be to add UI to guide users to resolve these problems.


For testing, I commented out all the rest of the web view code though, maybe that's the issue.

@aximut It shouldn't be an issue. After sending the query (and waiting its 500ms additional delay), it should work to sync Google apps and also to load the webview, which would otherwise close immediately. I don't know what the problem could be in your case.

@aximut
Copy link

aximut commented Apr 6, 2024

Ok, then I'll try with the new version soon.

@fynngodau
Copy link
Contributor Author

It seems the instance token + instance ID we are getting from GCM in https://github.com/microg/GmsCore/pull/2296/files#diff-3341dd523d63f6a4b7f5b44b9db7075c9a834e139fdc0fa945aafbb342942cceR48-R75 is somehow bad. The query works with it (which seems to indicate we are going in the right direction, as using a different sender constant for getting the instance ID – or no instance ID at all – would lead to a failing cryptauth request), but DeviceManagementScreenlockRequired keeps occurring even though the answer looks normal.

The same request with an instance ID taken from original GMS from the emulator works and leads to the account fully functioning.

I couldn't find out how original Google Play services generate their instance ID.

@aximut
Copy link

aximut commented Apr 23, 2024

That would explain why the request went through on my device but I'm still facing the errors

@fynngodau
Copy link
Contributor Author

fynngodau commented May 7, 2024

For future investigation regarding the above problem:

  • Instance ID generation should be attempted at client-side, following the pattern in the play-services-iid implementation, specifically:
    byte[] digest = MessageDigest.getInstance("SHA1").digest(keyPair.getPublic().getEncoded());
    digest[0] = (byte) (112 + (0xF & digest[0]) & 0xFF);
    return Base64.encodeToString(digest, 0, 8, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
  • Google Play services sometimes request the scope DeviceKeyRequest with sender/subtype/subscription 121252257541. This sound relevant, but is always rejected by the server on grounds of being an Invalid scope.

@fynngodau
Copy link
Contributor Author

Seemingly good senders / subtypes:

More info:

  • 121252257541 is not even a valid sender
  • 302798585788 leads to a token that leads to the cryptauth request being rejected on the grounds of containing an invalid argument.

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