-
Notifications
You must be signed in to change notification settings - Fork 41
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
Enable credentials using browser obtained token and cookie. #162
Conversation
I haven't had much time to test this yet, so use at your own risk. Also, we need to find a better way of obtaining the tokens to begin with. But one step at a time, the above steps work for me to log in and send messages at least. |
It's not working for me unfortunately. If I had to guess, it has something to do with the token encoding. If I try to put in the URL encoded version of the xoxd- cookie, it at least logs me out of my current slack session, otherwise it doesn't appear to be doing anything aside from returning "invalid_auth". I'm not sure if it makes a difference or not either, but I noticed you're using content dispositions instead of posting directly to the |
Also, as mentioned in another thread, at least during my testing with curl, the d-s cookie was required, or else it always resulted in "invalid_auth". Unless I'm missing something I didn't see it being passed in the debug window. |
Yes, I was wondering if this would show up. It was working for me, so I thought maybe it would be enough. I wonder what makes the difference... For the purposes of testing, can you simply try to hardcode the - g_string_append_printf(request, "Cookie: d=%s\r\n", sa->d_cookie);
+ g_string_append_printf(request, "Cookie: d=%s; d-s=12345\r\n", sa->d_cookie); If that does not work, can you post the debug log of the failing call? Make sure you get the "api call" and "api response" in particular. And make sure to scrub out your tokens so you don't share them to the public. Just FYI, it might take me a while to get back to you, since I'll be travelling after today.
I tried, but URL parameters do not work together with the |
@kacf Adding in the d-s cookie did indeed allow me to get passed the initial authentication issues. However, in my case since I think the workspace that I'm connecting to is a bit large, the connection appears to be closing before the entire API response is received at the client, and is therefore returning a "Invalid JSON response". Edit: I've confirmed it's when the plugin is retrieving the data from http://slack.com/api/user.list Edit2: So I think it may have had something to do with the debug window being opened, because the API response was bogging down pidgin. I was able to connect successfully and send / receive messages. Good work! |
Hi! Just for you to know, I've followed the instructions from the PR post and it looks that it's authenticating. For instance, here is this random excerpt: |
@moozhub: Good that it worked for you! If you are sure the @raul-klg: Could you save the whole debug window log during a login session? Remember to scrub all your tokens before posting. |
I started working on this, and I have some news. It turns out that However, again I'm not able to test any of this, so I ask @moozhub: If you revert to my original version without the
If so I believe we can fetch the cookie from there. |
@kacf I tested 8a09a6d and can confirm both of your questions:
Here is a copy of my debug log (slightly redacted), beginning at the Slack account connection:
|
Thanks @teddywing! But did your login ultimately work? Or did it fail later in the process? |
My login was successful and the Buddy List window populated with Slack channels. |
Ok. Unfortunately I need the log from someone whose login doesn't work. |
Ah, I missed that sorry. |
@kacf I have sent you an email with the logging. I hope it is helpful. |
Thanks @raul-klg! I've analyzed the log and I have a few questions:
|
Great! Thanks!
Yes. I issued Ctrl-Q after that time.
That's possible but I don't have access to all organization channels. What I see from the web interface is ~6 connections, 7 channels and ~10 direct messages.
I can try this again. |
I have to say that I got pidgin to sync with slack... after 10 minutes :) |
Alright, that's good! Then I have increased confidence that this is working. The issue with the slowness is then unrelated to this pull request. One quick way to get some improvement is to raise this to 1000 (the maximum), but I think the effect will still only be moderate at best. Other than that we may have to look at different ways of querying for conversations. |
you're genius! i was able to connect to my organization's workspase which uses SSO. |
@dylex: Sounds like this is working for quite a few people. We might want to think about merging it soon. The procedure for obtaining the token still needs a bit of cleaning up though. I have not really found a more robust way to get it than the instructions written above. I did look briefly into trying to extract them automatically using So then I suppose putting the manual instructions in the README is the best approach. Unless you have a better idea? |
One note for Bitlbee: I needed to manually set my token/password in a config file due to the way it’s formatted. Since Bitlbee treats spaces as word separators, only the first token was saved as my password with:
I’m not sure if there’s a way to quote the password for Bitlbee, but I ended up manually setting the password by encrypting it:
then pasting the result in |
That's a good point, we should probably separate them with a comma instead of a space. |
Rebased branch to get the fix for #174. |
For what it's worth, bitlbee accepted them quoted for me - |
I've tried the
Do you have any idea what's wrong? I've noticed the xoxd token is urlencoded and I also tried with the decoded token, but the result was the same... |
Hmm, I see the previous error when I choose to save the password in Pidgin. If I don't choose to store it, I get a different error:
|
Now I have successfully set up a new Slack account using this branch. So the previous errors were probably spurious... |
After pressing F12 I didn't see anywhere called storage, so these instructions seem incomplete. |
Which browser? |
I used Chromium/Chrome then Mozilla/Firefox so was able to try but it didn't work in BitlBee... I saw someone mention a newer/better way to do this but they never actually gave the link. |
The way it works is that you need two tokens from the browser. Currently, getting them is inconvenient, but let's start with the basics, and we can improve later. 1. Get the main token by entering the browser devtools while logged into Slack (normally F12). From there, select "Storage", then "Local Storage", "https://app.slack.com" and "localConfig_v2". From inside this value, fish out the value of the "token" key, which starts with "xoxc-". Make sure to get the whole token, and not the surrounding quotes. Paste this value in some temporary place. 2. Now move from "Local Storage" to "Cookies", and again "https://app.slack.com". Copy the value of the "d" cookie, which starts with "xoxd-". Paste this value after the one from the previous step, with exactly one space in between. 3. Take the two concatenated values, and paste them into the password field of the Slack account. The value should look like this: "xoxc-12345 xoxd-67890" (but much longer obviously). About the implementation: This requires using form based submission, because the JSON based API is broken and does not return the correct data, even with the same parameters (see issue #123). Therefore the way the token is passed, even the single token which already worked, is now changed to form data. Since `slack_api_get` is no longer a valid call when form based submission is used (it requires post), this function has been removed. Signed-off-by: Kristian Amlie <kristian.amlie@northern.tech>
Rebased to latest main branch, and added fix for new requirement, d-cookie in WebSocket requests. |
Started being required by Slack around 2023-09-19. Signed-off-by: Kristian Amlie <kristian.amlie@northern.tech>
Thanks for this work! I seem to be having an issue with a Slack account; I've follow the instructions for the formatted
I added a patch to hard-code a Let me know if/how to provide futher logs, if it would help! I'm only aware of checking |
@jleightcap: Which client are you using? |
@kacf Pidgin! |
If you check the log in the Pidgin Debug window (you need to keep it open while connection), can you post the log of:
Beware of private tokens in the output before posting. |
On Mon Oct 9, 2023 at 1:19 AM EDT, Kristian Amlie wrote:
If you check the log in the Pidgin Debug window (you need to keep it open while connection), can you post the log of:
1. `slack: api call: https://<xyz>.slack.com/api/rtm.connect` and the associated data below it.
2. The first `util: Response headers` which occurs after that.
3. The first few slack/RTM messages after point 2.
Beware of private tokens in the output before posting.
Absolutely.
I believe I've isolated/redacted the relevant log below.
```
(22:38:49) slack: api call: https://[REDACTED].slack.com/api/rtm.connect
POST /api/rtm.connect HTTP/1.0
Host: [REDACTED].slack.com
Content-Type: multipart/form-data; boundary=[REDACTED]
Content-Length: 485
Cookie: d=[REDACTED]; d-s=[REDACTED]
Content-Disposition: form-data; name="batch_presence_aware"
1
Content-Disposition: form-data; name="presence_sub"
true
Content-Disposition: form-data; name="token"
[REDACTED]
(22:38:49) util: requesting to fetch a URL
(22:38:49) dnsquery: Performing DNS lookup for [REDACTED].slack.com
(22:38:49) dns: Created new DNS child 103210, there are now 1 children.
(22:38:49) dns: Successfully sent DNS request to child 103210
(22:38:49) dns: Created new DNS child 103211, there are now 2 children.
(22:38:49) dns: Successfully sent DNS request to child 103211
(22:38:49) dns: Got response for '[REDACTED].slack.com'
(22:38:49) dnsquery: IP resolved for [REDACTED].slack.com
(22:38:49) proxy: Attempting connection to 34.205.195.66
(22:38:49) proxy: Connecting to [REDACTED].slack.com:443 with no proxy
(22:38:49) proxy: Connection in progress
(22:38:49) proxy: Connecting to [REDACTED].slack.com:443.
(22:38:49) proxy: Connected to [REDACTED].slack.com:443.
(22:38:49) nss: SSL version 3.4 using 128-bit AES-GCM with 128-bit AEAD MAC
Server Auth: 256-bit TLS 1.3, Key Exchange: 255-bit TLS 1.3, Compression: NULL
Cipher Suite Name: TLS_AES_128_GCM_SHA256
(22:38:49) nss: subject=CN=slack.com issuer=CN=R3,O=Let's Encrypt,C=US
(22:38:49) nss: subject=CN=R3,O=Let's Encrypt,C=US issuer=CN=ISRG Root X1,O=Internet Security Research Group,C=US
(22:38:49) nss: subject=CN=ISRG Root X1,O=Internet Security Research Group,C=US issuer=CN=DST Root CA X3,O=Digital Signature Trust Co.
(22:38:49) nss: partial certificate chain
(22:38:49) certificate/x509/tls_cached: Starting verify for [REDACTED].slack.com
(22:38:49) certificate/x509/tls_cached: Checking for cached cert...
(22:38:49) certificate/x509/tls_cached: ...Found cached cert
(22:38:49) nss/x509: Loading certificate from /home/jleightcap/.purple/certificates/x509/tls_peers/[REDACTED].slack.com
(22:38:49) certificate/x509/tls_cached: Peer cert matched cached
(22:38:49) nss/x509: Exporting certificate to /home/jleightcap/.purple/certificates/x509/tls_peers/[REDACTED].slack.com
(22:38:49) util: Writing file /home/jleightcap/.purple/certificates/x509/tls_peers/[REDACTED].slack.com
(22:38:49) nss: Trusting CN=slack.com
(22:38:49) certificate: Successfully verified certificate for [REDACTED].slack.com
(22:38:49) util: request constructed
(22:38:49) util: Response headers: 'HTTP/1.0 200 OK
date: Tue, 17 Oct 2023 02:38:49 GMT
server: Apache
vary: Accept-Encoding
x-slack-req-id: [REDACTED]
x-content-type-options: nosniff
x-xss-protection: 0
pragma: no-cache
cache-control: private, no-cache, no-store, must-revalidate
expires: Sat, 26 Jul 1997 05:00:00 GMT
content-type: application/json; charset=utf-8
x-accepted-oauth-scopes: rtm:stream,client
x-oauth-scopes: identify,read,post,client,apps
access-control-expose-headers: x-slack-req-id, retry-after
access-control-allow-headers: slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, x-b3-sampled, x-b3-flags
strict-transport-security: max-age=31536000; includeSubDomains; preload
referrer-policy: no-referrer
x-slack-unique-id: [REDACTED]
x-slack-backend: r
access-control-allow-origin: *
content-length: 216
via: 1.1 slack-prod.tinyspeck.com, envoy-www-iad-amztgedv, envoy-edge-iad-hoyufjuk
x-envoy-attempt-count: 1
x-envoy-upstream-service-time: 52
x-backend: main_normal main_canary_with_overflow main_control_with_overflow
x-server: slack-www-hhvm-main-iad-bmsl
x-slack-shared-secret-outcome: no-match
x-edge-backend: envoy-www
x-slack-edge-shared-secret-outcome: no-match
connection: close
'
(22:38:49) util: parsed 216
(22:38:49) slack: api response: {"ok":true,"url":"wss:\/\/wss-primary.slack.com\/websocket\/LEGACY_BOT:[REDACTED]","team":{"id":"[REDACTED]","name":"[REDACTED]","domain":"[REDACTED]"},"self":{"id":"[REDACTED]","name":"[REDACTED]"}}
(22:38:49) slack: user [REDACTED]: [REDACTED]
(22:38:49) slack: RTM URL: wss://wss-primary.slack.com/websocket/LEGACY_BOT:[REDACTED]
(22:38:49) dnsquery: Performing DNS lookup for wss-primary.slack.com
(22:38:49) dns: Successfully sent DNS request to child 103211
(22:38:49) dns: Got response for 'wss-primary.slack.com'
(22:38:49) dnsquery: IP resolved for wss-primary.slack.com
(22:38:49) proxy: Attempting connection to 3.211.37.212
(22:38:49) proxy: Connecting to wss-primary.slack.com:443 with no proxy
(22:38:49) proxy: Connection in progress
(22:38:49) proxy: Connecting to wss-primary.slack.com:443.
(22:38:49) proxy: Connected to wss-primary.slack.com:443.
(22:38:49) nss: SSL version 3.4 using 128-bit AES-GCM with 128-bit AEAD MAC
Server Auth: 2048-bit TLS 1.3, Key Exchange: 255-bit TLS 1.3, Compression: NULL
Cipher Suite Name: TLS_AES_128_GCM_SHA256
(22:38:49) nss: subject=CN=slack.com issuer=CN=R3,O=Let's Encrypt,C=US
(22:38:49) nss: subject=CN=R3,O=Let's Encrypt,C=US issuer=CN=ISRG Root X1,O=Internet Security Research Group,C=US
(22:38:49) nss: subject=CN=ISRG Root X1,O=Internet Security Research Group,C=US issuer=CN=DST Root CA X3,O=Digital Signature Trust Co.
(22:38:49) nss: partial certificate chain
(22:38:49) certificate/x509/tls_cached: Starting verify for wss-primary.slack.com
(22:38:49) certificate/x509/tls_cached: Checking for cached cert...
(22:38:49) certificate/x509/tls_cached: ...Found cached cert
(22:38:49) nss/x509: Loading certificate from /home/jleightcap/.purple/certificates/x509/tls_peers/wss-primary.slack.com
(22:38:49) certificate/x509/tls_cached: Peer cert matched cached
(22:38:49) nss/x509: Exporting certificate to /home/jleightcap/.purple/certificates/x509/tls_peers/wss-primary.slack.com
(22:38:49) util: Writing file /home/jleightcap/.purple/certificates/x509/tls_peers/wss-primary.slack.com
(22:38:49) nss: Trusting CN=slack.com
(22:38:49) certificate: Successfully verified certificate for wss-primary.slack.com
(22:38:49) slack: RTM 10:
(22:38:49) websocket: message 81 len 90
(22:38:49) slack: RTM 1: {"type":"error","error":{"msg":"invalid_auth","code":401,"source":"gatewayserver-iad-54"}}
(22:38:49) slack: Unhandled RTM type error
(22:38:49) slack: RTM 0: Connection closed
(22:38:49) connection: Connection error on 0x26fe1e0 (reason: 0 description: Connection closed)
(22:38:49) slack: RTM: Connection closed
(22:38:49) websocket: removing input 0
(22:38:49) account: Disconnecting account ***@***.***%[REDACTED].slack.com (0x2442b60)
(22:38:49) connection: Disconnecting connection 0x26fe1e0
(22:38:49) connection: Destroying connection 0x26fe1e0
```
Please let me know of any other information I can provide.
I'm happy to help however I can.
For context, I've declared this through Nix as:
```nix
purple-slack = pkgs.purple-slack.overrideAttrs (_: {
src = pkgs.fetchFromGitHub {
owner = "kacf";
repo = "slack-libpurple";
rev = "d276ba4a0854ea243cb995a6042acc1b936f7d45";
hash = "sha256-8VBifGHYqw9WJLADXqxibyMrh9bdOl6bj2hd1upL710=";
};
# patch to add hard-coded d-s cookie
patches = /* ... */;
});
```
where the patch is of the form
```
diff --git a/slack-api.c b/slack-api.c
index 75eb2da..286a234 100644
--- a/slack-api.c
+++ b/slack-api.c
@@ -147,7 +147,7 @@ Content-Length: %" G_GSIZE_FORMAT "\r\n",
path, host, delim, postdata->len);
if (sa->d_cookie) {
- g_string_append_printf(request, "Cookie: d=%s\r\n", sa->d_cookie);
+ g_string_append_printf(request, "Cookie: d=%s; d-s=[REDACTED]\r\n", sa->d_cookie);
}
g_string_append(request, "\r\n");
g_string_append(request, postdata->str);
```
|
Thanks, @jleightcap. Honestly I can't say. I've been comparing logs between what you posted and myself, and everything looks identical up to the point where it gives you authentication error. At this point I think your only bet is to open the browser debugging tools to see what the web client does, and try to replicate it. This might reveal a whole new set of issues though, since Slack has apparently redirected Pidgin to the legacy endpoint for some time, and the web client will probably try to use a newer endpoint. I don't know what the changes in the new protocol are. |
I appreciate the debugging effort, @kacf. I only have one Slack account to test with, if I find another I'll report results here. I'm unfortunately not well equipped to debug this further... |
These steps are easily automated and weechat's slack plugin has a python script todo pretty much that. I've modified that python script a little, so it prints out tokens in the format you specified in bullet point (3), and matches up the team name. Then added some code on top of this pull request, that can automatically invoke the python script. End result, is that the user just needs point to the location of the python script, and all the token stuff magically "just works", assuming you have a valid slack login in your browser. The code is berrange@60b72b2 @kacf feel free to add the above commit in this pull request if you desire, or I can submit this separately as a follow on pull req, as & when this one eventually merges. |
Continuation in #190. |
The way it works is that you need two tokens from the browser.
Currently, getting them is inconvenient, but let's start with the
basics, and we can improve later.
Get the main token by entering the browser devtools while logged
into Slack (normally F12). From there, select "Storage", then
"Local Storage", "https://app.slack.com" and "localConfig_v2". From
inside this value, fish out the value of the "token" key, which
starts with "xoxc-". Make sure to get the whole token, and not the
surrounding quotes. Paste this value in some temporary place.
Now move from "Local Storage" to "Cookies", and again
"https://app.slack.com". Copy the value of the "d" cookie, which
starts with "xoxd-". Paste this value after the one from the
previous step, with exactly one space in between.
Take the two concatenated values, and paste them into the password
field of the Slack account. The value should look like this:
"xoxc-12345 xoxd-67890" (but much longer obviously).
About the implementation: This requires using form based submission,
because the JSON based API is broken and does not return the correct
data, even with the same parameters (see issue #123). Therefore the
way the token is passed, even the single token which already worked,
is now changed to form data.
Since
slack_api_get
is no longer a valid call when form basedsubmission is used (it requires post), this function has been removed.
Signed-off-by: Kristian Amlie kristian.amlie@northern.tech