simonrob / email-oauth2-proxy

An IMAP/POP/SMTP proxy that transparently adds OAuth 2.0 authentication for email clients that don't support this method.
Apache License 2.0
814 stars 87 forks source link

Service Account for Gmail: AUTH response line too long #287

Open Jeelox opened 4 days ago

Jeelox commented 4 days ago

Hi, I'm trying to use email-oauth2-proxy to communicate with Gmail, but it's not working...

Here is my emailproxy.config file (after some anonymizations):

[SMTP-2465]
server_address = smtp.gmail.com
server_port = 465
local_address = 192.168.1.5
local_starttls = True
local_certificate_path = /etc/letsencrypt/live/mydomain.fr-0001/fullchain.pem
local_key_path = /etc/letsencrypt/live/mydomain.fr-0001/privkey.pem

[myuser@myproject.iam.gserviceaccount.com]
token_url = https://oauth2.googleapis.com/token
oauth2_scope = https://mail.google.com/
oauth2_flow = service_account
client_id = file
client_secret = /srv/emailproxy/myclientsecret.json
token_salt = *** generated from myclientsecret.json ***
token_iterations = 870000
access_token = *** generated from myclient.json ***
access_token_expiry = 1727381127

[emailproxy]
delete_account_token_on_password_error = True
encrypt_client_secret_on_first_use = False
use_login_password_as_client_credentials_secret = False
allow_catch_all_accounts = False

And the logs:

2024-09-26T23:05:28.825111+02:00 ubuntu Email OAuth 2.0 Proxy: New incoming connection to SMTP server at 192.168.1.5:2465 (STARTTLS) proxying smtp.gmail.com:465 (SSL/TLS)
2024-09-26T23:05:28.825175+02:00 ubuntu Email OAuth 2.0 Proxy: Accepting new connection from 172.25.0.2:47696 to SMTP server at 192.168.1.5:2465 (STARTTLS) proxying smtp.gmail.com:465 (SSL/TLS)
2024-09-26T23:05:28.836811+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) --> [ Client connected ]
2024-09-26T23:05:28.836878+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) <-> [ Starting TLS handshake ]
2024-09-26T23:05:28.867449+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) <-> [ TLSv1.3 handshake complete ]
2024-09-26T23:05:28.885819+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'220 smtp.gmail.com ESMTP ffacd0b85a97d-37cd575dd04sm721181f8f.114 - gsmtp\r\n'
2024-09-26T23:05:28.885974+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) <-- b'220 smtp.gmail.com ESMTP ffacd0b85a97d-37cd575dd04sm721181f8f.114 - gsmtp\r\n'
2024-09-26T23:05:28.887376+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) --> b'EHLO d427d39dd556\r\n'
2024-09-26T23:05:28.887495+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     --> b'EHLO d427d39dd556\r\n'
2024-09-26T23:05:28.899147+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-smtp.gmail.com at your service, [2a01:e0a:cb5:13f0:293:37ff:fe81:3792]\r\n'
2024-09-26T23:05:28.901207+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-SIZE 35882577\r\n'
2024-09-26T23:05:28.901461+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-8BITMIME\r\n'
2024-09-26T23:05:28.901645+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH\r\n'
2024-09-26T23:05:28.901838+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-ENHANCEDSTATUSCODES\r\n'
2024-09-26T23:05:28.902008+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-PIPELINING\r\n'
2024-09-26T23:05:28.902388+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-CHUNKING\r\n'
2024-09-26T23:05:28.902618+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250 SMTPUTF8\r\n'
2024-09-26T23:05:28.902917+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) <-- b'250-smtp.gmail.com at your service, [2a01:e0a:cb5:13f0:293:37ff:fe81:3792]\r\n250-SIZE 35882577\r\n250-8BITMIME\r\n250-AUTH PLAIN LOGIN\r\n250-ENHANCEDSTATUSCODES\r\n250-PIPELINING\r\n250-CHUNKING\r\n250-STARTTLS\r\n250 SMTPUTF8\r\n'
2024-09-26T23:05:28.903816+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) --> b'STARTTLS\r\n'
2024-09-26T23:05:28.904020+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) <-> [ Starting TLS handshake ]
2024-09-26T23:05:28.904196+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) <-- b'220 Ready to start TLS\r\n'
2024-09-26T23:05:28.918561+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) <-> [ TLSv1.3 handshake complete ]
2024-09-26T23:05:28.918829+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) --> b'EHLO d427d39dd556\r\n'
2024-09-26T23:05:28.918963+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) [ Successfully negotiated SMTP client STARTTLS connection ]
2024-09-26T23:05:28.919070+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     --> b'EHLO d427d39dd556\r\n'
2024-09-26T23:05:28.929094+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-smtp.gmail.com at your service, [2a01:e0a:cb5:13f0:293:37ff:fe81:3792]\r\n'
2024-09-26T23:05:28.929313+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-SIZE 35882577\r\n'
2024-09-26T23:05:28.929429+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-8BITMIME\r\n'
2024-09-26T23:05:28.929656+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH\r\n'
2024-09-26T23:05:28.929767+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-ENHANCEDSTATUSCODES\r\n'
2024-09-26T23:05:28.930078+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-PIPELINING\r\n'
2024-09-26T23:05:28.930294+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250-CHUNKING\r\n'
2024-09-26T23:05:28.930400+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'250 SMTPUTF8\r\n'
2024-09-26T23:05:28.930498+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) <-- b'250-smtp.gmail.com at your service, [2a01:e0a:cb5:13f0:293:37ff:fe81:3792]\r\n250-SIZE 35882577\r\n250-8BITMIME\r\n250-AUTH PLAIN LOGIN\r\n250-ENHANCEDSTATUSCODES\r\n250-PIPELINING\r\n250-CHUNKING\r\n250 SMTPUTF8\r\n'
2024-09-26T23:05:28.961542+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) --> b'AUTH PLAIN [[ Credentials removed from proxy log ]]\r\n'
2024-09-26T23:05:28.961924+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     --> b'AUTH XOAUTH2\r\n'
2024-09-26T23:05:28.972268+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465)     <-- b'334 \r\n'
2024-09-26T23:05:29.425591+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com)     --> b'[[ Credentials removed from proxy log ]]\r\n'
2024-09-26T23:05:29.437221+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com)     <-- b'500-5.5.6 Syntax error, AUTH response line too long. For more information, go to\r\n'
2024-09-26T23:05:29.437547+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) <-- b'500-5.5.6 Syntax error, AUTH response line too long. For more information, go to\r\n'
2024-09-26T23:05:29.437938+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465) <-- [ Server disconnected ]
2024-09-26T23:05:29.438649+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) --> [ Client disconnected ]
2024-09-26T23:05:29.439554+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com)     <-- b'500-5.5.6  https://support.google.com/a/answer/3221692 and review RFC 5321\r\n'
2024-09-26T23:05:29.439958+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) Caught server exception in subclass; client connection closed before data could be sent
2024-09-26T23:05:29.440589+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47696-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) --> [ Client disconnected ]

From my understanding: The STARTTLS from my client to emailproxy is working correctly. The TLS from email to gmail is working correctly. I'm wondering why we can see in the logs "--> b'AUTH PLAIN [[ Credentials removed from poxy long ]]\r\n'" The word PLAIN seems strange.

Thank you for your help.

simonrob commented 3 days ago

Thanks for reporting this.

Gmail's error response is not particularly helpful here, because the line lengths discussed in RFC 5321 (a limit of either 512 or 1000 characters depending on whether it is seen as command or text) are always going to be breached by the encoded OAuth 2.0 token, which is typically at least 2000-3000 characters long.

Instead, look at RFC 4954, which mentions almost as an aside: "At the time of writing of this document [in 2007], 12288 octets is considered to be a sufficient line length limit for handling of deployed authentication mechanisms."

It's interesting that this hasn't come up previously. Perhaps you are using a particularly long key, and Gmail has set a maximum length well above SMTP's core 512 / 1000 character limits, but below the RFC 4954 suggestion of 12288? (or your token is longer than this higher limit).

Either way, the smtp-line-length branch changes the SMTP token submission to split it over multiple lines. I went for 512 characters as a maximum because Gmail refers to the underlying SMTP limits rather than the longer RFC 4954 suggestion.

It's important to note that because of the ambiguity in the specification, which talks about the server's authentication buffer rather than the incoming line length, and doesn't actually define a way to split long lines, it's possible that this still won't work. If that's the case, you'll either need to reduce the size of the key you're using, or petition Gmail to increase this limit.

Please could you test this with your setup?

Jeelox commented 3 days ago

Thanks for answering.

It seems it doesn't work. Here are the logs: 2024-09-27T15:14:25.025502+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47212-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) --> b'[[ Credentials removed from proxy log ]]\r\n' 2024-09-27T15:14:25.034932+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47212-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) <-- b'501-5.5.2 Cannot Decode response. For more information, go to\r\n' 2024-09-27T15:14:25.035204+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47212-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) <-- b'501-5.5.2 Cannot Decode response. For more information, go to\r\n' 2024-09-27T15:14:25.035519+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47212-{192.168.1.5:2465}-smtp.gmail.com:465) <-- [ Server disconnected ] 2024-09-27T15:14:25.035985+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47212-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) --> [ Client disconnected ] 2024-09-27T15:14:25.036831+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47212-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) <-- b'501 5.5.2 https://support.google.com/a/answer/3221692 5b1f17b1804b1-42f57e2fe89sm26132635e9.40 - gsmtp\r\n' 2024-09-27T15:14:25.037686+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47212-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) Caught server exception in subclass; client connection closed before data could be sent 2024-09-27T15:14:25.038318+02:00 ubuntu Email OAuth 2.0 Proxy: SMTP (172.25.0.2:47212-{192.168.1.5:2465}-smtp.gmail.com:465; myuser@myproject.iam.gserviceaccount.com) --> [ Client disconnected ]

About the key length, Google is using a 2048 bits private key (recommanded), I tried to import a public key certificate related to a 1024 bits private key, and that the same as with the 2048 bits private key ("Cannot Decode response" with the smtp-line-length branch, and "AUTH response line too long" with the main branch).

Best Regards, Julien.

simonrob commented 2 days ago

In that case, I'd recommend temporarily disabling credential censoring, then trying again so you can a) see what its actual length is; and, b) decode the value (which is a JWT) to see whether anything unusual is present

Jeelox commented 1 day ago

The authentication message from the main branch is 1464 characters (+2 for \r\n), I can base64 decode it and get the user and the auth Bearer token. The authentication message from the smtp-line-length is also 1468 characters (+2 for \r\n), but can't be decoded (well, the first 86 characters are decoded, but then I have a gibberish with special characters and ending with "base64: invalid input".

I asked Gemini (From the Google Cloud) about the SMTP message maximum length. Below what he answered: "You're right to be concerned about the size of your SMTP message, especially with a long base64 encoded Bearer token. While there's no hard limit on the size of an SMTP message, Gmail has a soft limit of 10240 bytes for the entire message, including headers and body." And the documentation: https://cloud.google.com/iam/docs/reference/sts/rest/v1/TopLevel/token#response-body "Tokens can vary in size, depending in part on the size of mapped claims, up to a maximum of 12288 bytes (12 KB). Google reserves the right to change the token size and the maximum length at any time."

From my researches, the AUTH message can't be sent in multiple messages.

Looking at the main branch decoded AUTH. Here is what I get:

user=myuser@myproject.iam.gserviceaccount.comauth=Bearer ya29.c.c0ASRK0GbnUwM8sfy2cfo_SMmuOz6IX2gWkoW_IG... (I cut here). It doesn't seem suspicious (the "ya29.c" prefix is a common identifier for Google service account tokens. It's not part of the standard JWT structure but is used by Google to distinguish these tokens. And the \1 separator are not visible, but are there (confirmed from construct_oauth2_string).

I don't get why the SMTP server says it's too long. Is it a bug on the Google API?

Best Regards, Julien.

simonrob commented 1 day ago

You can ignore the smtp-line-length branch now – this was just an attempt at a workaround, and is clearly not having any effect here. The decoding failure is to do with the extra linebreaks that this branch adds. And the Gemini response is irrelevant because it relates to the SMTP message itself – your setup isn't getting to the point when it could send an email at the moment.

Does the Google token decode to something that looks valid? If so, I think the only real option is to find a way for me to be able to replicate this and investigate in detail. Currently I'm not able to make Gmail give me this error, so don't have any way to trace the issue.

Jeelox commented 1 day ago

Yes, the decoded Google token looks valid to me.

simonrob commented 1 day ago

In that case, unless you're able to provide me with a test account, I think it's best to contact Gmail / Workspace support to see whether they can investigate from their end.