mirror of
https://github.com/chatmail/relay.git
synced 2026-05-17 09:08:57 +00:00
Compare commits
5 Commits
link2xt/ec
...
fix-echobo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c541447f9b | ||
|
|
aed3803d17 | ||
|
|
9787a43902 | ||
|
|
e525d36899 | ||
|
|
6bbb5e07e5 |
@@ -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:
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user