mirror of
https://github.com/chatmail/relay.git
synced 2026-05-22 13:58:07 +00:00
fix: escape login and password when passed from dovecot to doveauth
This should allow to use / in the password
This commit is contained in:
@@ -98,6 +98,32 @@ def lookup_passdb(db, config: Config, user, cleartext_password):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def split_and_unescape(s):
|
||||||
|
"""Split strings using double quote as a separator and backslash as escape character
|
||||||
|
into parts."""
|
||||||
|
|
||||||
|
out = ""
|
||||||
|
i = 0
|
||||||
|
while i < len(s):
|
||||||
|
c = s[i]
|
||||||
|
if c == "\\":
|
||||||
|
# Skip escape character.
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# This will raise IndexError if there is no character
|
||||||
|
# after escape character. This is expected
|
||||||
|
# as this is an invalid input.
|
||||||
|
out += s[i]
|
||||||
|
elif c == '"':
|
||||||
|
# Separator
|
||||||
|
yield out
|
||||||
|
out = ""
|
||||||
|
else:
|
||||||
|
out += c
|
||||||
|
i += 1
|
||||||
|
yield out
|
||||||
|
|
||||||
|
|
||||||
def handle_dovecot_request(msg, db, config: Config):
|
def handle_dovecot_request(msg, db, config: Config):
|
||||||
short_command = msg[0]
|
short_command = msg[0]
|
||||||
if short_command == "L": # LOOKUP
|
if short_command == "L": # LOOKUP
|
||||||
@@ -107,7 +133,9 @@ def handle_dovecot_request(msg, db, config: Config):
|
|||||||
# do not attempt to read any other parts for compatibility.
|
# do not attempt to read any other parts for compatibility.
|
||||||
keyname = parts[0]
|
keyname = parts[0]
|
||||||
|
|
||||||
namespace, type, *args = keyname.split("/")
|
namespace, type, args = keyname.split("/", 2)
|
||||||
|
args = list(split_and_unescape(args))
|
||||||
|
|
||||||
reply_command = "F"
|
reply_command = "F"
|
||||||
res = ""
|
res = ""
|
||||||
if namespace == "shared":
|
if namespace == "shared":
|
||||||
|
|||||||
@@ -52,8 +52,9 @@ def test_too_high_db_version(db):
|
|||||||
|
|
||||||
|
|
||||||
def test_handle_dovecot_request(db, example_config):
|
def test_handle_dovecot_request(db, example_config):
|
||||||
|
# Test that password can contain ", ', \ and /
|
||||||
msg = (
|
msg = (
|
||||||
"Lshared/passdb/laksjdlaksjdlaksjdlk12j3l1k2j3123/"
|
'Lshared/passdb/laksjdlaksjdlak\\\\sjdlk\\"12j\\\'3l1/k2j3123"'
|
||||||
"some42123@chat.example.org\tsome42123@chat.example.org"
|
"some42123@chat.example.org\tsome42123@chat.example.org"
|
||||||
)
|
)
|
||||||
res = handle_dovecot_request(msg, db, example_config)
|
res = handle_dovecot_request(msg, db, example_config)
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
uri = proxy:/run/dovecot/doveauth.socket:auth
|
uri = proxy:/run/dovecot/doveauth.socket:auth
|
||||||
iterate_disable = yes
|
iterate_disable = yes
|
||||||
default_pass_scheme = plain
|
default_pass_scheme = plain
|
||||||
password_key = passdb/%w/%u
|
# %E escapes characters " (double quote), ' (single quote) and \ (backslash) with \ (backslash).
|
||||||
user_key = userdb/%u
|
# See <https://doc.dovecot.org/configuration_manual/config_file/config_variables/#modifiers>
|
||||||
|
# for documentation.
|
||||||
|
#
|
||||||
|
# We escape user-provided input and use double quote as a separator.
|
||||||
|
password_key = passdb/%Ew"%Eu
|
||||||
|
user_key = userdb/%Eu
|
||||||
|
|||||||
Reference in New Issue
Block a user