mirror of
https://github.com/chatmail/relay.git
synced 2026-05-11 08:24:37 +00:00
Compare commits
9 Commits
link2xt/au
...
quota-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b6f6f1c50 | ||
|
|
f4cf4ab955 | ||
|
|
48d890ee82 | ||
|
|
3c57155c40 | ||
|
|
cf1be90115 | ||
|
|
5781d3b04e | ||
|
|
862b09d268 | ||
|
|
9b438a7a96 | ||
|
|
a107fb3cca |
@@ -16,7 +16,7 @@ def encrypt_password(password: str):
|
||||
password = password.encode("ascii")
|
||||
# https://doc.dovecot.org/configuration_manual/authentication/password_schemes/
|
||||
process = subprocess.Popen(
|
||||
["doveadm", "pw", "-s", "BLF-CRYPT"],
|
||||
["doveadm", "pw", "-s", "SHA512-CRYPT"],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
@@ -59,7 +59,7 @@ def handle_dovecot_request(msg, db):
|
||||
if short_command == "L": # LOOKUP
|
||||
parts = msg[1:].split("\t")
|
||||
keyname, user = parts[:2]
|
||||
namespace, type, arg = keyname.split("/", 3)
|
||||
namespace, type, *args = keyname.split("/")
|
||||
reply_command = "F"
|
||||
res = ""
|
||||
if namespace == "shared":
|
||||
@@ -70,7 +70,7 @@ def handle_dovecot_request(msg, db):
|
||||
else:
|
||||
reply_command = "N"
|
||||
elif type == "passdb":
|
||||
res = lookup_passdb(db, user, password=arg)
|
||||
res = lookup_passdb(db, user, password=args[0])
|
||||
if res:
|
||||
reply_command = "O"
|
||||
else:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
uri = proxy:/run/dovecot/doveauth.socket:auth
|
||||
iterate_disable = yes
|
||||
default_pass_scheme = plain
|
||||
password_key = passdb/%w
|
||||
user_key = userdb/%u
|
||||
password_key = passdb/%w/%u
|
||||
user_key = userdb/%u
|
||||
|
||||
@@ -4,10 +4,14 @@ protocols = imap lmtp
|
||||
|
||||
auth_mechanisms = plain
|
||||
|
||||
auth_verbose = yes
|
||||
auth_debug = yes
|
||||
auth_debug_passwords = yes
|
||||
auth_verbose_passwords = plain
|
||||
mail_plugins = quota
|
||||
mail_debug = yes
|
||||
|
||||
# uncomment this if you want to debug authentication and user creation
|
||||
#auth_verbose = yes
|
||||
#auth_debug = yes
|
||||
#auth_debug_passwords = yes
|
||||
#auth_verbose_passwords = plain
|
||||
|
||||
# Authentication for system users.
|
||||
passdb {
|
||||
@@ -59,13 +63,28 @@ mail_privileged_group = vmail
|
||||
# Enable IMAP COMPRESS (RFC 4978).
|
||||
# <https://datatracker.ietf.org/doc/html/rfc4978.html>
|
||||
protocol imap {
|
||||
mail_plugins = $mail_plugins imap_zlib
|
||||
mail_plugins = $mail_plugins imap_zlib imap_quota
|
||||
}
|
||||
|
||||
protocol lmtp {
|
||||
mail_plugins = $mail_plugins quota
|
||||
}
|
||||
|
||||
plugin {
|
||||
imap_compress_deflate_level = 6
|
||||
}
|
||||
|
||||
plugin {
|
||||
# for now we define static quota-rules for all users
|
||||
quota = maildir:User quota
|
||||
quota_rule = *:storage=100M
|
||||
quota_max_mail_size=30M
|
||||
quota_grace = 0
|
||||
quota_over_flag_value = TRUE
|
||||
}
|
||||
|
||||
|
||||
|
||||
service lmtp {
|
||||
user=vmail
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ submission inet n - y - - smtpd
|
||||
-o smtpd_recipient_restrictions=
|
||||
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
|
||||
-o milter_macro_daemon_name=ORIGINATING
|
||||
-o content_filter=filter:unix:private/filtemail
|
||||
-o content_filter=filter:unix:private/filtermail
|
||||
smtps inet n - y - - smtpd
|
||||
-o syslog_name=postfix/smtps
|
||||
-o smtpd_tls_wrappermode=yes
|
||||
|
||||
@@ -4,6 +4,7 @@ import imaplib
|
||||
import smtplib
|
||||
import itertools
|
||||
import pytest
|
||||
import time
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -49,12 +50,13 @@ class SmtpConn:
|
||||
|
||||
@pytest.fixture
|
||||
def gencreds(maildomain):
|
||||
prefix = str(time.time())
|
||||
count = itertools.count()
|
||||
|
||||
def gen():
|
||||
while 1:
|
||||
num = next(count)
|
||||
yield f"user{num}@{maildomain}", f"password{num}"
|
||||
yield f"user{prefix}_{num}@{maildomain}", f"password{prefix}_{num}"
|
||||
|
||||
return lambda: next(gen())
|
||||
|
||||
|
||||
@@ -12,6 +12,19 @@ class TestDovecot:
|
||||
imap.connect()
|
||||
imap.login(user, password)
|
||||
|
||||
def test_login_same_password(self, imap, gencreds):
|
||||
"""Test two different users logging in with the same password.
|
||||
|
||||
This ensures that authentication process does not confuse the users
|
||||
by using only the password hash as a key.
|
||||
"""
|
||||
user1, password1 = gencreds()
|
||||
user2, _password2 = gencreds()
|
||||
imap.connect()
|
||||
imap.login(user1, password1)
|
||||
imap.connect()
|
||||
imap.login(user2, password1)
|
||||
|
||||
def test_login_fail(self, imap, gencreds):
|
||||
user, password = gencreds()
|
||||
imap.connect()
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
import os.path
|
||||
import random
|
||||
import time
|
||||
|
||||
|
||||
class TestMailSending:
|
||||
def test_one_on_one(self, cmfactory, lp):
|
||||
ac1, ac2 = cmfactory.get_online_accounts(2)
|
||||
@@ -9,3 +14,32 @@ class TestMailSending:
|
||||
lp.sec("wait for ac2 to receive message")
|
||||
msg2 = ac2._evtracker.wait_next_incoming_message()
|
||||
assert msg2.text == "message0"
|
||||
|
||||
def test_exceed_quota(self, cmfactory, lp, tmpdir):
|
||||
ac1, ac2 = cmfactory.get_online_accounts(2)
|
||||
chat = cmfactory.get_accepted_chat(ac1, ac2)
|
||||
|
||||
ac2.set_config("download_limit", 1024 * 2) # set download_limit to 2 KB avoid downloading all those 5MB files
|
||||
|
||||
lp.sec("ac1: send 25 5 MB files to ac2")
|
||||
alphanumeric = "abcdefghijklmnopqrstuvwxyz1234567890"
|
||||
for i in range(25):
|
||||
attachment = tmpdir / f"attachment{i}"
|
||||
with open(attachment, "w+") as f:
|
||||
for j in range(1024 * 1024 * 5):
|
||||
f.write(random.choice(alphanumeric))
|
||||
|
||||
print("Sent out msg", str(i))
|
||||
chat.send_file(str(attachment))
|
||||
|
||||
ac2.wait_next_incoming_message()
|
||||
lp.sec("ac2: check that at least one message failed")
|
||||
failed = False
|
||||
for i in range(25):
|
||||
if chat.get_messages()[i].is_out_failed():
|
||||
failed = True
|
||||
print(chat.get_messages()[i].get_message_info())
|
||||
try:
|
||||
assert failed
|
||||
except:
|
||||
import pdb; pdb.set_trace()
|
||||
|
||||
7
plan.txt
7
plan.txt
@@ -2,13 +2,10 @@
|
||||
|
||||
## Dovecot goals/steps
|
||||
|
||||
2. (holger) per-user storage quota (adaptive)
|
||||
a) define a static 100MB per-user quota
|
||||
|
||||
3. automatic expiry of messages older than M days
|
||||
- automatic expiry of messages older than M days
|
||||
- delete unconditionally messages older than 40 days
|
||||
|
||||
4. limit: max-connections per account
|
||||
- limit: configure max-connections per account
|
||||
|
||||
|
||||
## Filtermail
|
||||
|
||||
@@ -7,7 +7,7 @@ domain = os.environ.get("CHATMAIL_DOMAIN", "c3.testrun.org")
|
||||
print("connecting")
|
||||
conn = imaplib.IMAP4_SSL(domain)
|
||||
print("logging in")
|
||||
conn.login(f"measure{time.time()}", "pass")
|
||||
conn.login(f"imapcapa", "pass")
|
||||
status, res = conn.capability()
|
||||
for capa in sorted(res[0].decode().split()):
|
||||
print(capa)
|
||||
|
||||
1
scripts/measure_tls_and_logins.py
Normal file → Executable file
1
scripts/measure_tls_and_logins.py
Normal file → Executable file
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import time
|
||||
import imaplib
|
||||
|
||||
Reference in New Issue
Block a user