himmelblau-idm / himmelblau

Azure Entra ID Authentication, with PAM and NSS modules.
GNU General Public License v3.0
34 stars 8 forks source link

Single sign on for Edge #48

Closed dmulder closed 3 weeks ago

dmulder commented 1 year ago

As mentioned here, we need to supply creds to $HOME/.cache/Microsoft/Edge/IdentityCache/OneAuth/ to allow single sign on for edge.

dmulder commented 9 months ago

We're going to need to integrate our broker with msal, such as here. We may need to either fork msal for openSUSE, or maintain our own set of patches, since Microsoft has made it clear they are unwilling to cooperate on this.

dmulder commented 7 months ago

@dirkjanm has already figured out some method for doing this. See here: https://github.com/dirkjanm/ROADtools/blob/1e2b1af3bce3640b34e3e7646d2a91e479df649e/roadtx/roadtools/roadtx/main.py#L390

dmulder commented 6 months ago

@dirkjanm has already figured out some method for doing this. See here: https://github.com/dirkjanm/ROADtools/blob/1e2b1af3bce3640b34e3e7646d2a91e479df649e/roadtx/roadtools/roadtx/main.py#L390

This is using selenium to inject a PRT during an auth attempt. This probably isn't the best approach.

dmulder commented 6 months ago

The correct way is probably going to use WebAuthn.

fmoessbauer commented 2 months ago

to allow single sign on for edge.

Note, that the PRT SSO cookie injection is not just for SSO, but also to pass the conditional access policies requiring a trusted device.

This is using selenium to inject a PRT during an auth attempt. This probably isn't the best approach.

This approach is what Edge is doing on an Intune-enabled Linux device: It communicates with the microsoft-identity-broker service via DBus (com.microsoft.identity.Broker1) to get the token and then injects that into the HTTP requests hitting https://login.microsoftonline.com/*. Ideally, himmelblau can offer a drop-in replacement for this DBus service, so existing tools can directly use it without any modifications. Despite this not being an "official" interface, it looks quite stable and people start using it:

Disclaimer: The first two are developed by me. cc @nsballmann

dmulder commented 2 months ago

I'd love to see this integrated!

dmulder commented 2 months ago

@fmoessbauer do you have any documentation on how the dbus service works?

dmulder commented 2 months ago

@fmoessbauer, could you provide me an example of what the responses from the Broker dbus service look like? I see you're calling into getAccounts, acquirePrtSsoCookie, and acquireTokenSilently. What do those respond with?

nsballmann commented 2 months ago

@dmulder I created a support request with MS requesting this exact information. After quite some time they came back with:

So, our hope is that they release this in MSAL.Python and this hopefully is sufficient "documentation".

I was under the impression that your msal rust crate already supports talking to the identity brokers. Did I just imagine this (I haven't looked at the code, yet)?

dmulder commented 2 months ago

I was under the impression that your msal rust crate already supports talking to the identity brokers. Did I just imagine this (I haven't looked at the code, yet)?

My msal crate is able to join the device and request a PRT. So in essence, we have the broker capabilities, but without the dbus service. So getting this working is just a matter of understanding how the dbus service works.

We've also been in discussions with MS to try to get more documentation for a Broker. They have been stonewalling us for the most part.

dmulder commented 2 months ago
  • "Yes, we know MSAL doesn't support talking to the identity brokers, yet, but please use MSAL for that." 🤨

That discussion makes it sound like MS is referring to their cloud service as the 'identity brokers'. The terminology is very confusing. In my discussions with MS, IIUC the Broker is the client piece (himmelblau in our case) that distributes PRTs, etc to services on the host. So in that sense, yes we are already communicating with the 'identity brokers' to retrieve PRTs, access tokens, refresh tokens, etc.

fmoessbauer commented 2 months ago

@fmoessbauer, could you provide me an example of what the responses from the Broker dbus service look like?

Sure. I'm currently working on an OSS c library similar to MSAL for the communication with the broker. This will likely be OSS'ed in a couple of days. This also comes with a tool to interact with the broker from the command line (mostly for debugging). The idea / interfaces are pretty similar to what you already can see in the evolution patches from above. From a semantics POV the request / response is more or less what you find in the official MSAL documentation.

I see you're calling into getAccounts, acquirePrtSsoCookie, and acquireTokenSilently. What do those respond with?

getAccounts: Responds with a JSON array of accounts (basically data from the AD like username, realm, ...). These accounts are the ones registered with Intune. Usually, you just want to take the first one.

acquirePrtSsoCookie: This takes an account (just one entry you get from getAccounts), a ssoURL (the url the browser hits) and some static parameters. It responds with:

{
[...],
"cookieContent": "<JWT>",
"cookieName": "x-ms-RefreshTokenCredential"
}

This data then needs to be injected either as cookie or as http header into the request that hits login.microsoftonline.com. For details, have a look at the python script in the linux-entra-sso browser plugin.

acquireTokenSilently: Identical to msal.ClientApplication.acquire_token_silent

dmulder commented 2 months ago

Sure. I'm currently working on an OSS c library similar to MSAL for the communication with the broker. This will likely be OSS'ed in a couple of days. This also comes with a tool to interact with the broker from the command line (mostly for debugging). The idea / interfaces are pretty similar to what you already can see in the evolution patches from above. From a semantics POV the request / response is more or less what you find in the official MSAL documentation.

I already provide C bindings to my msal (now called libhimmelblau) crate, and it's being maintained by the Samba team. See here: https://gitlab.com/samba-team/libhimmelblau If you run make, it builds a c library and c header file. There is a C example source here. https://crates.io/crates/libhimmelblau

dmulder commented 2 months ago

I'm currently working on an OSS c library similar to MSAL for the communication with the broker.

There are also Python bindings, FYI.

fmoessbauer commented 2 months ago

I already provide C bindings to my msal (now called libhimmelblau) crate, and it's being maintained by the Samba team. See here: https://gitlab.com/samba-team/libhimmelblau

I know, and eventually I'm also planning to use that. Unfortunately it is a pain in the *** to get rust code integrated into Linux distros (which is an inherent problem of languages that come with their own package manager). Also, the libhimmelblau does not intend to talk to the proprietary MS broker, but instead be a replacement for that. My library should gap this transition period, where applications already have to interact with PRTs, but there is not yet a full OSS solution.

In the end, the "native" C lib is just glue code that can be replaced later on.

dmulder commented 2 months ago

I know, and eventually I'm also planning to use that. Unfortunately it is a pain in the *** to get rust code integrated into Linux distros (which is an inherent problem of languages that come with their own package manager). Also, the libhimmelblau does not intend to talk to the proprietary MS broker, but instead be a replacement for that. My library should gap this transition period, where applications already have to interact with PRTs, but there is not yet a full OSS solution.

In the end, the "native" C lib is just glue code that can be replaced later on.

Ah, that makes sense. One of my goals is to have libhimmelblau/msal fetch PRTs from the Intune Broker as well, for folks who would prefer using the proprietary binaries. I haven't done any work on that though.

fmoessbauer commented 2 months ago

One of my goals is to have libhimmelblau/msal fetch PRTs from the Intune Broker as well, for folks who would prefer using the proprietary binaries. I haven't done any work on that though.

That's great, looking forward. Just keep in mind that the whole story stands and falls with broad distro support, as each and every application that accesses MS resources needs to integrate with the library. That's one of the reasons why I wrote this in C, despite having to jiggle around with JSON data. Tools like gnome-online-accounts and evolution are written in C.

dmulder commented 2 months ago

One of my goals is to have libhimmelblau/msal fetch PRTs from the Intune Broker as well, for folks who would prefer using the proprietary binaries. I haven't done any work on that though.

That's great, looking forward. Just keep in mind that the whole story stands and falls with broad distro support, as each and every application that accesses MS resources needs to integrate with the library. That's one of the reasons why I wrote this in C, despite having to jiggle around with JSON data. Tools like gnome-online-accounts and evolution are written in C.

I already have backing from RH and SUSE (and it's already packaged on openSUSE). We have Debian packages in the works.

FYI, I'm a SUSE employee and a Samba team member. There's already a great deal of community support backing this project.

dmulder commented 2 months ago

This is all being integrated into Samba, FYI. So when I get a Broker DBUS service functioning, you'll be able to join via samba-tool and have SSO.

fmoessbauer commented 2 months ago

We have Debian packages in the works.

For us, especially the Debian support is important. Ideally we also can have backports to already get these features on bookworm. And that's where I'm still a bit skeptic w.r.t. Rust. But let's see.

This is all being integrated into Samba, FYI. So when I get a Broker DBUS service functioning, you'll be able to join via samba-tool and have SSO.

Yep. That would make things much easier. BTW: I already watched the talk on YT :smile:

dmulder commented 2 months ago

@fmoessbauer I created a simple broker dbus service, but it never sees messages from your plugin: https://gist.github.com/dmulder/cf09cc56fa5667279a3f4e5cfe3928fb Do you see anything I've done obviously wrong here?

nsballmann commented 2 months ago

@dmulder just to clarify on what I mean with "Microsoft Identity Brokers" in the context of

That discussion makes it sound like MS is referring to their cloud service as the 'identity brokers'. The terminology is very confusing. In my discussions with MS, IIUC the Broker is the client piece (himmelblau in our case) that distributes PRTs, etc to services on the host. So in that sense, yes we are already communicating with the 'identity brokers' to retrieve PRTs, access tokens, refresh tokens, etc.

I mean these two systemd services:

z003dswv@z003dswv-P15:~$ systemctl --user --no-pager status microsoft-identity-broker.service 
â—Ź microsoft-identity-broker.service - Microsoft Identity Broker Service
     Loaded: loaded (/usr/lib/systemd/user/microsoft-identity-broker.service; static)
     Active: active (running) since Wed 2024-07-10 07:59:30 CEST; 10h ago
    Process: 10546 ExecStartPre=sh -c if [ -d /home/z003dswv/.config/msft-identity-broker/ ]; then mv /home/z003dswv/.config/msft-identity-broker/* /home/z003dswv/.config/microsoft-identity-broker/; rmdir /home/z003dswv/.config/msft-identity-broker/; fi (code=exited, status=0/SUCCESS)
    Process: 10547 ExecStartPre=sh -c if [ -d /home/z003dswv/.config/log/msft-identity-broker/ ]; then mv /home/z003dswv/.config/log/msft-identity-broker/* /home/z003dswv/.config/log/microsoft-identity-broker/; rmdir /home/z003dswv/.config/log/msft-identity-broker/; fi (code=exited, status=0/SUCCESS)
   Main PID: 10548 (java)
      Tasks: 121 (limit: 37936)
     Memory: 711.0M
        CPU: 7min 15.109s
     CGroup: /user.slice/user-1001.slice/user@1001.service/background.slice/microsoft-identity-broker.service
             └─10548 /usr/lib/jvm/java-11-openjdk-amd64/bin/java -classpath /opt/microsoft/identity-broker/lib/LinuxBrokerPackage-2.0.1.jar:/opt/microsoft/identity-broker/lib/LinuxBroker-2.0.1.jar:/opt/microsof…

Jul 10 18:15:34 z003dswv-P15 microsoft-identity-broker[10548]: I/SharedPreferencesAccountCredentialCache:getAccounts: [2024-07-10 16:15:34 - thread_id: 80, correlation_id: 9c637668-a02d-4f6e-b0e5…[1] Accounts...
Jul 10 18:15:34 z003dswv-P15 microsoft-identity-broker[10548]: I/SharedPreferencesAccountCredentialCache:getAccounts: [2024-07-10 16:15:34 - thread_id: 80, correlation_id: 9c637668-a02d-4f6e-b0e5…[1] Accounts...
Jul 10 18:15:35 z003dswv-P15 microsoft-identity-broker[10548]: I/MicrosoftFamilyOAuth2TokenCache:loadByFamilyIdWithAggregatedAccountData: [2024-07-10 16:15:35 - thread_id: 80, correlation_id: 9c6…or this account
Jul 10 18:15:35 z003dswv-P15 microsoft-identity-broker[10548]: I/LocalAuthenticationResult: [2024-07-10 16:15:35 - thread_id: 80, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e62b - ] Id Token type: IdToken
Jul 10 18:15:35 z003dswv-P15 microsoft-identity-broker[10548]: I/LocalAuthenticationResult: [2024-07-10 16:15:35 - thread_id: 80, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e62b - ] Construc…ord null: false
Jul 10 18:15:35 z003dswv-P15 microsoft-identity-broker[10548]: I/AbstractBrokerController:getAuthenticationResultFromCache: [2024-07-10 16:15:35 - thread_id: 80, correlation_id: 9c637668-a02d-4f6…sult from cache
Jul 10 18:15:35 z003dswv-P15 microsoft-identity-broker[10548]: W/Telemetry: [2024-07-10 16:15:35 - thread_id: 80, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e62b - ] No telemetry observer set.
Jul 10 18:15:35 z003dswv-P15 microsoft-identity-broker[10548]: I/CommandDispatcher:submitSilent: [2024-07-10 16:15:35 - thread_id: 80, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e62b - ] Com…acheable : true
Jul 10 18:15:35 z003dswv-P15 microsoft-identity-broker[10548]: I/LinuxBrokerServiceOperation:acquireTokenSilently: [2024-07-10 16:15:35 - thread_id: 39, correlation_id: 9c637668-a02d-4f6e-b0e5-3d…e5-3d85ddc6e62b
Jul 10 18:15:35 z003dswv-P15 microsoft-identity-broker[10548]: I/BrokerDBusV1Impl:acquireTokenSilently: [2024-07-10 16:15:35 - thread_id: 39, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e62b …e5-3d85ddc6e62b
Hint: Some lines were ellipsized, use -l to show in full.
z003dswv@z003dswv-P15:~$ sudo systemctl --no-pager status microsoft-identity-device-broker.service 
[sudo] Passwort fĂĽr z003dswv: 
â—Ź microsoft-identity-device-broker.service - Microsoft Identity Device Broker Service
     Loaded: loaded (/lib/systemd/system/microsoft-identity-device-broker.service; static)
     Active: active (running) since Wed 2024-07-10 07:59:31 CEST; 10h ago
    Process: 11052 ExecStartPre=sh -c if [ -d /var/lib/msft-identity-device-broker/ ]; then mv /var/lib/msft-identity-device-broker/* /var/lib/microsoft-identity-device-broker/; rmdir /var/lib/msft-identity-device-broker/; fi (code=exited, status=0/SUCCESS)
    Process: 11125 ExecStartPre=sh -c if [ -d /var/log/msft-identity-device-broker/ ]; then mv /var/log/msft-identity-device-broker/* /var/log/microsoft-identity-device-broker/; rmdir /var/log/msft-identity-device-broker/; fi (code=exited, status=0/SUCCESS)
   Main PID: 11129 (java)
      Tasks: 47 (limit: 37936)
     Memory: 939.7M
        CPU: 2min 37.712s
     CGroup: /system.slice/microsoft-identity-device-broker.service
             └─11129 /usr/lib/jvm/java-11-openjdk-amd64/bin/java -classpath /opt/microsoft/identity-broker/lib/LinuxBrokerPackage-2.0.1.jar:/opt/microsoft/identity-broker/lib/LinuxBroker-2.0.1.jar:/opt/microsof…

Jul 10 18:15:34 z003dswv-P15 microsoft-identity-device-broker[11129]: I/DeviceBrokerDBusV1Impl:loadKeyPair: [2024-07-10 16:15:34 - thread_id: 25, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e6…5-3d85ddc6e62b
Jul 10 18:15:34 z003dswv-P15 microsoft-identity-device-broker[11129]: I/loadKeyPair: [2024-07-10 16:15:34 - thread_id: 26, correlation_id: UNSET - ] Received method call from UID [1001], with corr…3d85ddc6e62b].
Jul 10 18:15:34 z003dswv-P15 microsoft-identity-device-broker[11129]: I/LinuxBrokerPlatformComponents:getDbFileRootDir: [2024-07-10 16:15:34 - thread_id: 26, correlation_id: 9c637668-a02d-4f6e-b0e…-device-broker
Jul 10 18:15:34 z003dswv-P15 microsoft-identity-device-broker[11129]: I/DeviceBrokerDBusV1Impl:loadKeyPair: [2024-07-10 16:15:34 - thread_id: 26, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e6…5-3d85ddc6e62b
Jul 10 18:15:34 z003dswv-P15 microsoft-identity-device-broker[11129]: I/loadKeyPair: [2024-07-10 16:15:34 - thread_id: 25, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e62b - ] Received method …3d85ddc6e62b].
Jul 10 18:15:34 z003dswv-P15 microsoft-identity-device-broker[11129]: I/LinuxBrokerPlatformComponents:getDbFileRootDir: [2024-07-10 16:15:34 - thread_id: 25, correlation_id: 9c637668-a02d-4f6e-b0e…-device-broker
Jul 10 18:15:34 z003dswv-P15 microsoft-identity-device-broker[11129]: I/DeviceBrokerDBusV1Impl:loadKeyPair: [2024-07-10 16:15:34 - thread_id: 25, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e6…5-3d85ddc6e62b
Jul 10 18:15:34 z003dswv-P15 microsoft-identity-device-broker[11129]: I/loadKeyPair: [2024-07-10 16:15:34 - thread_id: 26, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e62b - ] Received method …3d85ddc6e62b].
Jul 10 18:15:34 z003dswv-P15 microsoft-identity-device-broker[11129]: I/LinuxBrokerPlatformComponents:getDbFileRootDir: [2024-07-10 16:15:34 - thread_id: 26, correlation_id: 9c637668-a02d-4f6e-b0e…-device-broker
Jul 10 18:15:34 z003dswv-P15 microsoft-identity-device-broker[11129]: I/DeviceBrokerDBusV1Impl:loadKeyPair: [2024-07-10 16:15:34 - thread_id: 26, correlation_id: 9c637668-a02d-4f6e-b0e5-3d85ddc6e6…5-3d85ddc6e62b
Hint: Some lines were ellipsized, use -l to show in full.
z003dswv@z003dswv-P15:~$

That stem from https://packages.microsoft.com/ubuntu/22.04/prod/pool/main/m/microsoft-identity-broker/ version 2.0.1 and are a dependency from the intune-portal package (by the Entra product group at MS (in contrast to the Intune product group)).

And these are "just" some bloaty and resource hungry Java applications that I haven't had the time yet to throw into Ghidra or your Java decompiler of choice.

dmulder commented 2 months ago

That stem from https://packages.microsoft.com/ubuntu/22.04/prod/pool/main/m/microsoft-identity-broker/ version 2.0.1 and are a dependency from the intune-portal package (by the Entra product group at MS (in contrast to the Intune product group)).

And these are "just" some bloaty and resource hungry Java applications that I haven't had the time yet to throw into Ghidra or your Java decompiler of choice.

By that definition, yes. Himmelblau is a Broker. See the design spec. [MS-OAPXBC] defines how a Broker works, and that's how Himmelblau operates.

nsballmann commented 2 months ago

By that definition, yes. Himmelblau is a Broker.

But which doesn't provide the MS D-Bus interface... yet, right?

dmulder commented 2 months ago

By that definition, yes. Himmelblau is a Broker.

But which doesn't provider the MS D-Bus interface... yet, right?

Yes, exactly.

nsballmann commented 2 months ago

K, got it. I would love to have Himmelblau as a drop-in replacement and will try to support you wherever my time allows it, especially in the direction of testing.

fmoessbauer commented 2 months ago

I created a simple broker dbus service, but it never sees messages from your plugin:

That is looking fine. Did manage to see DBus calls from the extension? For debugging, I recommend to just run the python script in interactive mode. E.g. python3 ./linux-entra-sso.py --interactive acquirePrtSsoCookie.

dmulder commented 2 months ago

@fmoessbauer is MS providing a system dbus service or a session dbus service? It looks like it's a session bus to me.

fmoessbauer commented 2 months ago

It looks like it's a session bus to me.

Yes. They provide both, but the relevant one (the one apps talk to) is a session bus. The other is likely for internal communication between the microsoft-identity-device-broker system service and the microsoft-identity-broker user service.