Compare commits

..

5 Commits

Author SHA1 Message Date
missytake
c541447f9b CI: wait with VRFY test until echobot is logged in 2024-05-02 16:21:08 +02:00
missytake
aed3803d17 wait a minute with tests to avoid VRFY creating echo@ 2024-05-02 15:27:57 +02:00
missytake
9787a43902 echo: re-enable test 2024-05-02 13:49:09 +02:00
missytake
e525d36899 changelog for #276 2024-05-02 13:48:38 +02:00
missytake
6bbb5e07e5 echo: skip test as long as it's broken 2024-05-02 13:33:11 +02:00
5 changed files with 21 additions and 73 deletions

View File

@@ -4,7 +4,6 @@ import time
import sys import sys
import json import json
import crypt import crypt
from pathlib import Path
from socketserver import ( from socketserver import (
UnixStreamServer, UnixStreamServer,
StreamRequestHandler, StreamRequestHandler,
@@ -46,32 +45,23 @@ def is_allowed_to_create(config: Config, user, cleartext_password) -> bool:
return False return False
localpart, domain = parts localpart, domain = parts
if localpart == "echo":
# echobot account should not be created in the database
return False
if ( if (
len(localpart) > config.username_max_length len(localpart) > config.username_max_length
or len(localpart) < config.username_min_length or len(localpart) < config.username_min_length
): ):
logging.warning( if localpart != "echo":
"localpart %s has to be between %s and %s chars long", logging.warning(
localpart, "localpart %s has to be between %s and %s chars long",
config.username_min_length, localpart,
config.username_max_length, config.username_min_length,
) config.username_max_length,
)
return False
return True return True
def get_user_data(db, config: Config, user): def get_user_data(db, config: Config, user):
if user == f"echo@{config.mail_domain}":
return dict(
home=f"/home/vmail/mail/{config.mail_domain}/echo@{config.mail_domain}",
uid="vmail",
gid="vmail",
)
with db.read_connection() as conn: with db.read_connection() as conn:
result = conn.get_user(user) result = conn.get_user(user)
if result: if result:
@@ -86,21 +76,6 @@ def lookup_userdb(db, config: Config, user):
def lookup_passdb(db, config: Config, user, cleartext_password): def lookup_passdb(db, config: Config, user, cleartext_password):
if user == f"echo@{config.mail_domain}":
# Echobot writes password it wants to log in with into /run/echobot/password
try:
password = Path("/run/echobot/password").read_text()
except Exception:
logging.exception("Exception when trying to read /run/echobot/password")
return None
return dict(
home=f"/home/vmail/mail/{config.mail_domain}/echo@{config.mail_domain}",
uid="vmail",
gid="vmail",
password=encrypt_password(password),
)
with db.write_transaction() as conn: with db.write_transaction() as conn:
userdata = conn.get_user(user) userdata = conn.get_user(user)
if userdata: if userdata:

View File

@@ -3,17 +3,14 @@
it will echo back any message that has non-empty text and also supports the /help command. it will echo back any message that has non-empty text and also supports the /help command.
""" """
import logging import logging
import os import os
import sys import sys
import subprocess
from deltachat_rpc_client import Bot, DeltaChat, EventType, Rpc, events from deltachat_rpc_client import Bot, DeltaChat, EventType, Rpc, events
from pathlib import Path
from chatmaild.config import read_config
from chatmaild.newemail import create_newemail_dict from chatmaild.newemail import create_newemail_dict
from chatmaild.config import read_config
hooks = events.HookCollection() hooks = events.HookCollection()
@@ -78,23 +75,9 @@ def main():
account = accounts[0] if accounts else deltachat.add_account() account = accounts[0] if accounts else deltachat.add_account()
bot = Bot(account, hooks) bot = Bot(account, hooks)
config = read_config(sys.argv[1])
# Create password file
if bot.is_configured():
password = bot.account.get_config("mail_pw")
else:
password = create_newemail_dict(config)["password"]
Path("/run/echobot/password").write_text(password)
# Give the user which doveauth runs as access to the password file.
subprocess.run(
["/usr/bin/setfacl", "-m", "user:vmail:r", "/run/echobot/password"],
check=True,
)
if not bot.is_configured(): if not bot.is_configured():
config = read_config(sys.argv[1])
password = create_newemail_dict(config).get("password")
email = "echo@" + config.mail_domain email = "echo@" + config.mail_domain
bot.configure(email, password) bot.configure(email, password)
bot.run_forever() bot.run_forever()

View File

@@ -477,7 +477,6 @@ def deploy_chatmail(config_path: Path) -> None:
groups=["opendkim"], groups=["opendkim"],
system=True, system=True,
) )
server.user(name="Create echobot user", user="echobot", system=True)
server.shell( server.shell(
name="Fix file owner in /home/vmail", name="Fix file owner in /home/vmail",

View File

@@ -7,20 +7,6 @@ Environment="PATH={remote_venv_dir}:$PATH"
Restart=always Restart=always
RestartSec=30 RestartSec=30
User=echobot
Group=echobot
# Create /var/lib/echobot
StateDirectory=echobot
# Create /run/echobot
#
# echobot stores /run/echobot/password
# with a password there, which doveauth then reads.
RuntimeDirectory=echobot
WorkingDirectory=/var/lib/echobot
# Apply security restrictions suggested by # Apply security restrictions suggested by
# systemd-analyze security echobot.service # systemd-analyze security echobot.service
CapabilityBoundingSet= CapabilityBoundingSet=
@@ -30,10 +16,7 @@ NoNewPrivileges=true
PrivateDevices=true PrivateDevices=true
PrivateMounts=true PrivateMounts=true
PrivateTmp=true PrivateTmp=true
PrivateUsers=true
# We need to know about doveauth user to give it access to /run/echobot/password
PrivateUsers=false
ProtectClock=true ProtectClock=true
ProtectControlGroups=true ProtectControlGroups=true
ProtectHostname=true ProtectHostname=true

View File

@@ -2,6 +2,7 @@ import pytest
import threading import threading
import queue import queue
import socket import socket
import time
from chatmaild.config import read_config from chatmaild.config import read_config
from cmdeploy.cmdeploy import main from cmdeploy.cmdeploy import main
@@ -81,7 +82,14 @@ def test_concurrent_logins_same_account(
assert login_results.get() assert login_results.get()
def test_no_vrfy(chatmail_config): def test_no_vrfy(chatmail_config, remote):
found = False
while not found:
for line in remote.iter_output(logcmd="journalctl -u echobot"):
print(line)
if "successfully logged into imap server" in line:
found = True
break
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((chatmail_config.mail_domain, 25)) sock.connect((chatmail_config.mail_domain, 25))
banner = sock.recv(1024) banner = sock.recv(1024)