mirror of
https://github.com/Mailu/Mailu.git
synced 2025-01-18 03:21:36 +02:00
Merge #2838
2838: Authentication failed for email clients when the password contained a non latin-1 character. r=mergify[bot] a=Diman0 ## What type of PR? bug fix ## What does this PR do? Fixes a bug that results in authentication failing for email clients when the password contains a non latin-1 character. Issue was caused by the header Auth-Password being returned with non latin-1 characters. Headers must always be latin-1 encoded. Resolved the issue by url encoding the password. Since the returned password is only used as a partial hash for the rate limiter, I did not add code for un-quoting the password in the /internal/email endpoint. ### Related issue(s) - closes #2837 ## Prerequisites Before we can consider review and merge, please make sure the following list is done and checked. If an entry in not applicable, you can check it or remove it from the list. - [x] In case of feature or enhancement: documentation updated accordingly - [x] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/workflow.html#changelog) entry file. Co-authored-by: Dimitri Huisman <diman@huisman.xyz> Co-authored-by: Florent Daigniere <nextgens@users.noreply.github.com>
This commit is contained in:
commit
6f3ee32351
@ -111,7 +111,6 @@ def handle_authentication(headers):
|
||||
"Auth-Server": server,
|
||||
"Auth-User": user_email,
|
||||
"Auth-User-Exists": is_valid_user,
|
||||
"Auth-Password": password,
|
||||
"Auth-Port": port
|
||||
}
|
||||
status, code = get_status(protocol, "authentication")
|
||||
@ -120,7 +119,6 @@ def handle_authentication(headers):
|
||||
"Auth-Error-Code": code,
|
||||
"Auth-User": user_email,
|
||||
"Auth-User-Exists": is_valid_user,
|
||||
"Auth-Password": password,
|
||||
"Auth-Wait": 0
|
||||
}
|
||||
# Unexpected
|
||||
|
@ -6,6 +6,7 @@ import flask
|
||||
import flask_login
|
||||
import base64
|
||||
import sqlalchemy.exc
|
||||
import urllib
|
||||
|
||||
@internal.route("/auth/email")
|
||||
def nginx_authentication():
|
||||
@ -30,6 +31,7 @@ def nginx_authentication():
|
||||
if int(flask.request.headers['Auth-Login-Attempt']) < 10:
|
||||
response.headers['Auth-Wait'] = '3'
|
||||
return response
|
||||
raw_password = urllib.parse.unquote(headers["Auth-Pass"])
|
||||
headers = nginx.handle_authentication(flask.request.headers)
|
||||
response = flask.Response()
|
||||
for key, value in headers.items():
|
||||
@ -52,7 +54,14 @@ def nginx_authentication():
|
||||
if not is_port_25:
|
||||
utils.limiter.exempt_ip_from_ratelimits(client_ip)
|
||||
elif is_valid_user:
|
||||
utils.limiter.rate_limit_user(username, client_ip, password=response.headers.get('Auth-Password', None))
|
||||
password = None
|
||||
try:
|
||||
password = raw_password.encode("iso8859-1").decode("utf8")
|
||||
except:
|
||||
app.logger.warn(f'Received undecodable password for {username} from nginx: {raw_password!r}')
|
||||
utils.limiter.rate_limit_user(username, client_ip, password=None)
|
||||
else:
|
||||
utils.limiter.rate_limit_user(username, client_ip, password=password)
|
||||
elif not is_from_webmail:
|
||||
utils.limiter.rate_limit_ip(client_ip, username)
|
||||
return response
|
||||
|
@ -8,4 +8,5 @@ docker compose -f tests/compose/core/docker-compose.yml exec -T admin flask mail
|
||||
docker compose -f tests/compose/core/docker-compose.yml exec -T admin flask mailu admin admin mailu.io 'password' --mode=update || exit 1
|
||||
docker compose -f tests/compose/core/docker-compose.yml exec -T admin flask mailu user user mailu.io 'password' || exit 1
|
||||
docker compose -f tests/compose/core/docker-compose.yml exec -T admin flask mailu user 'user/with/slash' mailu.io 'password' || exit 1
|
||||
docker compose -f tests/compose/core/docker-compose.yml exec -T admin flask mailu user 'user_UTF8' mailu.io 'password€' || exit 1
|
||||
echo "User testing successful!"
|
||||
|
@ -7,25 +7,31 @@ import sys
|
||||
import managesieve
|
||||
|
||||
SERVER='localhost'
|
||||
USERNAME='user@mailu.io'
|
||||
PASSWORD='password'
|
||||
USERNAME='user_UTF8@mailu.io'
|
||||
PASSWORD='password€'
|
||||
#https://github.com/python/cpython/issues/73936
|
||||
#SMTPlib does not support UTF8 passwords.
|
||||
USERNAME_ASCII='user@mailu.io'
|
||||
PASSWORD_ASCII='password'
|
||||
|
||||
|
||||
def test_imap(server, username, password):
|
||||
auth = lambda data : f'\x00{username}\x00{password}'
|
||||
print(f'Authenticating to imaps://{username}:{password}@{server}:993/')
|
||||
with imaplib.IMAP4_SSL(server) as conn:
|
||||
conn.login(username, password)
|
||||
conn.authenticate('PLAIN', auth)
|
||||
conn.noop()
|
||||
print('OK')
|
||||
print(f'Authenticating to imaps://{username}:{password}@{server}:143/')
|
||||
with imaplib.IMAP4(server) as conn:
|
||||
conn.starttls()
|
||||
conn.login(username, password)
|
||||
conn.authenticate('PLAIN', auth)
|
||||
conn.noop()
|
||||
print('OK')
|
||||
print(f'Authenticating to imap://{username}:{password}@{server}:143/')
|
||||
try:
|
||||
with imaplib.IMAP4(server) as conn:
|
||||
conn.login(username, password)
|
||||
conn.authenticate('PLAIN', auth)
|
||||
print(f'Authenticating to imap://{username}:{password}@{server}:143/ worked without STARTTLS!')
|
||||
sys.exit(102)
|
||||
except imaplib.IMAP4.error:
|
||||
@ -121,7 +127,7 @@ def test_managesieve(server, username, password):
|
||||
if m.login('', username, password) != 'OK':
|
||||
print(f'Authenticating to sieve://{username}:{password}@{server}:4190/ has failed!')
|
||||
sys.exit(109)
|
||||
|
||||
|
||||
if m.listscripts()[0] != 'OK':
|
||||
print(f'Listing scripts failed!')
|
||||
sys.exit(110)
|
||||
@ -130,5 +136,7 @@ def test_managesieve(server, username, password):
|
||||
if __name__ == '__main__':
|
||||
test_imap(SERVER, USERNAME, PASSWORD)
|
||||
test_pop3(SERVER, USERNAME, PASSWORD)
|
||||
test_SMTP(SERVER, USERNAME, PASSWORD)
|
||||
test_SMTP(SERVER, USERNAME_ASCII, PASSWORD_ASCII)
|
||||
test_managesieve(SERVER, USERNAME, PASSWORD)
|
||||
#https://github.com/python/cpython/issues/73936
|
||||
#SMTPlib does not support UTF8 passwords.
|
1
towncrier/newsfragments/2837.bugfix
Normal file
1
towncrier/newsfragments/2837.bugfix
Normal file
@ -0,0 +1 @@
|
||||
Authentication failed for email clients when the password contained a non latin-1 character.
|
Loading…
x
Reference in New Issue
Block a user