slack-libpurple
slack-libpurple copied to clipboard
SAML authentication
I haven't been able to use my corporate Slack account in Pidgin as it needs authentication to happen in the web browser.
The call to https://slack.com/api/auth.findUser returns an error:
{"ok":false,"error":"sso_nonra"}
I've come up with some scripting which solves this for Chime — we use the browser to perform authentication just like the Slack desktop app does, and capture the slack:// URI that the browser ends up at.
This registers the appropriate x-scheme-handler/chime and provides a Python script to 'prod' the resulting token into Pidgin via D-Bus. It should probably work for Slack too with a little work in the auth code. https://github.com/awslabs/pidgin-chime/commit/b430eba40f9e5e389cfe2f78e37a68e3cc3aa40a
The output we get from the browser looks something like this:
slack://T123D5R2HSR/magic-login/2019235634234-c5776930c24d4403a24dffa0b9070068dca0e48fcc874cb2b82d256a6bb9eb92
That's interesting. As a starting point proof-of-concept, could we add the authentication code as a login authentication option and use it that way? (I presume it only works once.) Once that's working, we could figure out how to get it connected. See also #115
@dylex I'm going to hopefully help try bringing this issue back from the dead... I followed some of the instructions put forward in #115 ... using the auth token gathered from the web development tool in the 'API token' field, the debug window shows the following:
slack: api response: {"ok":false,"error":"invalid_auth"}
However, when going to the URL the plugin is trying to talk to with my browser it's returning a true result with the websocket address, I believe a cookie written out by the auth source is allowing the true result. I'm not an expert on how all of it works, but is there a way we can possibly pass in cookies to the address it's sending API calls to? I'm attempting to SAML auth from an Azure AD source.
We certainly could add a configuration option to pass a cookie. If you want to try it yourself, you could just add the cookie header to the request manually (in slack-api.c
around line 150). One concern is how long these cookies last, but certainly it's better than nothing if it works. Let me know if adding the cookie works for you and I'll add an option, or if you need help testing it.
@dylex Yes, it works with the cookie. It was a cookie that was created last night when I was working on this so it should work for a little while at least.. Unfortunately I don't have enough C++ know-how to test with the plugin (my attempt at creating a simple string and passing it along in the postdata and getting it to compile have failed), I was simply passing in the Cookie header into a curl command I wrote up, but good news is it will work assuming we are passing it and it will return a result with the appropriate wss:// address.
It's a python project, but maybe this PR of wee-slack can offer pointers.
That PR adds support for a d
cookie. We could certainly add the same option to just include a configured d
cookie. @moozhub, is that the cookie that you needed? If so, I'll add it.
As suggested by the referenced PR there are others passed along in the cookie request, the d cookie is one of them yes.. but the others are:
b, d-s, documentation_banner_cookie, lc, no_download_ssb_banner, OptanonConsent, show_download_ssb_banner, shown_download_ssb_modal, shown_ssb_redirect_page, ssb_instance_id, and x
I'm not sure which ones are actually necessary if it makes a difference, I was passing all of them when submitting the request with curl.
I think only the d
cookie is necessary. I tested it just now.
However, the wss://wss-primary.slack.com/
endpoint, which the Slack client connects to instead of the rtm.connect
endpoint that we've been relying on, requires a token in addition to the cookie. It starts with xoxc-
, but I have not yet figured out where it comes from.
Oh, hold on, this is what you were talking about in #115: It's available in Dev Tools -> Storage -> Local Storage -> https://app.slack.com -> localConfig_v2 -> token
. So I think I've pieced it together now, although I've only tried this in curl.
Both d
cookie and token
are required in every call. d
is passed in a Cookie header, and token
is passed as form/query data. The official client appears to be using POST
for almost everything, even when just listing data, so in that case it is passed as form data.
The wss://wss-primary.slack.com/
Web Socket call passes the token in the query parameters however, which is why I spotted it first.
(On a side note: the official client gets the Web Socket address from the /api/client.getWebSocketURL
call, which we might consider using instead of a hardcoded address).
I'll have to put this down for now due to time constraints, but I hope the above is useful. If nothing happens until I have a new spare moment I might jump on this implementation though. We started enforcing 2FA, and this is bothering me quite a bit...
@kacf just an update.. I was helping out the weechat guys and going through the process of elimination on what cookies are required to actually pass, it was determined by some testing I did that the d-s
cookie also needs to be passed, otherwise it will invalidate the token and sign me out. Another thing is how the token is URL encoded, at least with my curl test, if it weren't URL encoded it would also invalidate the token.
I've just posted a pull request here, would be great if more people can test it.
Even if you don't use 2FA, but the traditional login which already works, it would be great if you can test it. I no longer have access to this method of logging in, so I cannot verify that I didn't break it in the process of enabling this.
Mentioned wee-slack PR dealing with xoxc
tokens before. Note they've closed it now as resolved -- perhaps worth taking a look again?
I noticed that auth.findUser returns this now : api response: {"ok":false,"error":"unknown_method","req_method":"auth.findUser"}
would this help with it?
The findUser
endpoint is not called when using the token as described in https://github.com/dylex/slack-libpurple/pull/162, so yes, it helps, albeit indirectly.
How can I verify if that is used? I rebuild the plugin with the patch applied, set my pw to the token plus cooky still the same issue.
At least for Pidgin: If you open the Debug Window (from Help menu) before trying to log in, the first slack: api call
should be to <SOMETHING>/rtm.connect
. If it's not then you have not set up the tokens correctly.