mirror of
https://github.com/chatmail/relay.git
synced 2026-05-19 12:28:06 +00:00
www: generate dclogin codes for IPv4-only relays
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
"""CGI script for creating new accounts."""
|
"""CGI script for creating new accounts."""
|
||||||
|
|
||||||
import ipaddress
|
|
||||||
import json
|
import json
|
||||||
import secrets
|
import secrets
|
||||||
import string
|
import string
|
||||||
@@ -15,16 +14,6 @@ ALPHANUMERIC = string.ascii_lowercase + string.digits
|
|||||||
ALPHANUMERIC_PUNCT = string.ascii_letters + string.digits + string.punctuation
|
ALPHANUMERIC_PUNCT = string.ascii_letters + string.digits + string.punctuation
|
||||||
|
|
||||||
|
|
||||||
def wrap_ip(host):
|
|
||||||
if host.startswith("[") and host.endswith("]"):
|
|
||||||
return host
|
|
||||||
try:
|
|
||||||
ipaddress.ip_address(host)
|
|
||||||
return f"[{host}]"
|
|
||||||
except ValueError:
|
|
||||||
return host
|
|
||||||
|
|
||||||
|
|
||||||
def create_newemail_dict(config: Config):
|
def create_newemail_dict(config: Config):
|
||||||
user = "".join(
|
user = "".join(
|
||||||
secrets.choice(ALPHANUMERIC) for _ in range(config.username_max_length)
|
secrets.choice(ALPHANUMERIC) for _ in range(config.username_max_length)
|
||||||
@@ -33,16 +22,24 @@ def create_newemail_dict(config: Config):
|
|||||||
secrets.choice(ALPHANUMERIC_PUNCT)
|
secrets.choice(ALPHANUMERIC_PUNCT)
|
||||||
for _ in range(config.password_min_length + 3)
|
for _ in range(config.password_min_length + 3)
|
||||||
)
|
)
|
||||||
return dict(email=f"{user}@{wrap_ip(config.mail_domain)}", password=f"{password}")
|
return dict(
|
||||||
|
email=f"{user}@{config.mail_domain_deliverable}", password=f"{password}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_dclogin_url(email, password):
|
def create_dclogin_url(config, email, password):
|
||||||
"""Build a dclogin: URL with credentials and self-signed cert acceptance.
|
"""Build a dclogin: URL with credentials and self-signed cert acceptance.
|
||||||
|
|
||||||
Uses ic=3 (AcceptInvalidCertificates) so chatmail clients
|
Uses ic=3 (AcceptInvalidCertificates) so chatmail clients
|
||||||
can connect to servers with self-signed TLS certificates.
|
can connect to servers with self-signed TLS certificates.
|
||||||
"""
|
"""
|
||||||
return f"dclogin:{quote(email, safe='@')}?p={quote(password, safe='')}&v=1&ic=3"
|
if config.mail_domain != config.mail_domain_deliverable:
|
||||||
|
imap_host = "&ih=" + config.mail_domain
|
||||||
|
smtp_host = "&sh=" + config.mail_domain
|
||||||
|
else:
|
||||||
|
imap_host = ""
|
||||||
|
smtp_host = ""
|
||||||
|
return f"dclogin:{quote(email, safe='@[]')}?p={quote(password, safe='')}&v=1{imap_host}{smtp_host}&ic=3"
|
||||||
|
|
||||||
|
|
||||||
def print_new_account():
|
def print_new_account():
|
||||||
@@ -51,7 +48,9 @@ def print_new_account():
|
|||||||
|
|
||||||
result = dict(email=creds["email"], password=creds["password"])
|
result = dict(email=creds["email"], password=creds["password"])
|
||||||
if config.tls_cert_mode == "self":
|
if config.tls_cert_mode == "self":
|
||||||
result["dclogin_url"] = create_dclogin_url(creds["email"], creds["password"])
|
result["dclogin_url"] = create_dclogin_url(
|
||||||
|
config, creds["email"], creds["password"]
|
||||||
|
)
|
||||||
|
|
||||||
print("Content-Type: application/json")
|
print("Content-Type: application/json")
|
||||||
print("")
|
print("")
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ def example_config(make_config):
|
|||||||
return make_config("chat.example.org")
|
return make_config("chat.example.org")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def ipv4_config(make_config):
|
||||||
|
return make_config("1.3.3.7")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def maildomain(example_config):
|
def maildomain(example_config):
|
||||||
return example_config.mail_domain
|
return example_config.mail_domain
|
||||||
|
|||||||
@@ -19,24 +19,35 @@ def test_create_newemail_dict(example_config):
|
|||||||
assert ac1["password"] != ac2["password"]
|
assert ac1["password"] != ac2["password"]
|
||||||
|
|
||||||
|
|
||||||
def test_create_newemail_dict_ip(make_config):
|
def test_create_newemail_dict_ip(ipv4_config):
|
||||||
config = make_config("1.2.3.4")
|
ac = create_newemail_dict(ipv4_config)
|
||||||
ac = create_newemail_dict(config)
|
assert ac["email"].endswith("@[1.3.3.7]")
|
||||||
assert ac["email"].endswith("@[1.2.3.4]")
|
|
||||||
|
|
||||||
|
|
||||||
def test_create_dclogin_url():
|
def test_create_dclogin_url(example_config):
|
||||||
url = create_dclogin_url("user@example.org", "p@ss w+rd")
|
addr = "user@example.org"
|
||||||
|
password = "p@ss w+rd"
|
||||||
|
url = create_dclogin_url(example_config, addr, password)
|
||||||
assert url.startswith("dclogin:")
|
assert url.startswith("dclogin:")
|
||||||
assert "v=1" in url
|
assert "v=1" in url
|
||||||
assert "ic=3" in url
|
assert "ic=3" in url
|
||||||
|
|
||||||
assert "user@example.org" in url
|
assert addr in url
|
||||||
# password special chars must be encoded
|
# password special chars must be encoded
|
||||||
assert "p%40ss" in url
|
assert "p%40ss" in url
|
||||||
assert "w%2Brd" in url
|
assert "w%2Brd" in url
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_dclogin_url_ipv4(ipv4_config):
|
||||||
|
addr = "user@[1.3.3.7]"
|
||||||
|
password = "p@ss w+rd"
|
||||||
|
url = create_dclogin_url(ipv4_config, addr, password)
|
||||||
|
assert url.startswith("dclogin:")
|
||||||
|
assert "v=1" in url
|
||||||
|
assert "ic=3" in url
|
||||||
|
assert addr in url
|
||||||
|
|
||||||
|
|
||||||
def test_print_new_account(capsys, monkeypatch, maildomain, tmpdir, example_config):
|
def test_print_new_account(capsys, monkeypatch, maildomain, tmpdir, example_config):
|
||||||
monkeypatch.setattr(chatmaild.newemail, "CONFIG_PATH", str(example_config._inipath))
|
monkeypatch.setattr(chatmaild.newemail, "CONFIG_PATH", str(example_config._inipath))
|
||||||
print_new_account()
|
print_new_account()
|
||||||
|
|||||||
Reference in New Issue
Block a user