add logic for dynamic IP lookup for deltachat links and install #31
This commit is contained in:
parent
d4b4b5a9e0
commit
8bb7792ee3
2 changed files with 64 additions and 2 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import io
|
import io
|
||||||
import re
|
import re
|
||||||
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from app import app
|
from app import app
|
||||||
|
|
@ -26,6 +27,39 @@ from install_madmail import run_madmail_installer
|
||||||
CHANGES_REQUIRING_RESTART = ['wifi_password', 'ssid', 'enable_access_point', 'enable_chat', 'enable_delta_chat', 'butterbox_hostname', 'ssh_access_settings', 'root_account_settings', 'root_password']
|
CHANGES_REQUIRING_RESTART = ['wifi_password', 'ssid', 'enable_access_point', 'enable_chat', 'enable_delta_chat', 'butterbox_hostname', 'ssh_access_settings', 'root_account_settings', 'root_password']
|
||||||
RASPAP_INSTALLED = os.path.exists("/var/www/html/raspap")
|
RASPAP_INSTALLED = os.path.exists("/var/www/html/raspap")
|
||||||
|
|
||||||
|
def resolve_butterbox_ip() -> str:
|
||||||
|
"""Best-effort lookup of the address clients should use to reach this box.
|
||||||
|
|
||||||
|
``BUTTERBOX_DEFAULT_IP`` is only correct while the box serves its own
|
||||||
|
access point. When it's joined to another network its address differs, so
|
||||||
|
try to discover the real one and only fall back to the configured default.
|
||||||
|
"""
|
||||||
|
hostname = get_setting('butterbox_hostname') or app.config['BUTTERBOX_HOSTNAME']
|
||||||
|
|
||||||
|
# 1. Resolve the box's own mDNS/.local name. This is the same name the
|
||||||
|
# DeltaChat link uses for the mail host, so avahi/nss-mdns is present.
|
||||||
|
try:
|
||||||
|
ip = socket.gethostbyname(f"{hostname}.local")
|
||||||
|
if ip and not ip.startswith("127."):
|
||||||
|
return ip
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 2. Fall back to the address of the primary outbound interface. The
|
||||||
|
# connect() picks a route without sending any packets.
|
||||||
|
try:
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||||
|
s.connect(("8.8.8.8", 80))
|
||||||
|
ip = s.getsockname()[0]
|
||||||
|
if ip and not ip.startswith("127."):
|
||||||
|
return ip
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 3. Give up and use the configured access-point default.
|
||||||
|
return app.config['BUTTERBOX_DEFAULT_IP']
|
||||||
|
|
||||||
|
|
||||||
def gen_username() -> str:
|
def gen_username() -> str:
|
||||||
words = top_n_list("en", 5000)
|
words = top_n_list("en", 5000)
|
||||||
prefix = random.randint(1000, 9999)
|
prefix = random.randint(1000, 9999)
|
||||||
|
|
@ -370,7 +404,7 @@ def messaging():
|
||||||
|
|
||||||
@app.route("/deltachat_credentials", methods=["POST"])
|
@app.route("/deltachat_credentials", methods=["POST"])
|
||||||
def deltachat_credentials():
|
def deltachat_credentials():
|
||||||
ip = app.config['BUTTERBOX_DEFAULT_IP']
|
ip = resolve_butterbox_ip()
|
||||||
username = gen_username()
|
username = gen_username()
|
||||||
password = gen_password()
|
password = gen_password()
|
||||||
hostname = f"{get_setting('butterbox_hostname')}.local"
|
hostname = f"{get_setting('butterbox_hostname')}.local"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,36 @@
|
||||||
import pexpect
|
import pexpect
|
||||||
import json
|
import json
|
||||||
|
import socket
|
||||||
from app import app
|
from app import app
|
||||||
from subprocess import run
|
from subprocess import run
|
||||||
|
|
||||||
|
def resolve_butterbox_ip(hostname):
|
||||||
|
"""Best-effort lookup of the box's current address, falling back to the
|
||||||
|
configured default. Mirrors app.routes.resolve_butterbox_ip but avoids a
|
||||||
|
circular import (routes imports this module) and reuses the hostname that
|
||||||
|
was already loaded from settings.txt."""
|
||||||
|
# 1. Resolve the box's own mDNS/.local name.
|
||||||
|
try:
|
||||||
|
ip = socket.gethostbyname(f"{hostname}.local")
|
||||||
|
if ip and not ip.startswith("127."):
|
||||||
|
return ip
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 2. Fall back to the address of the primary outbound interface. The
|
||||||
|
# connect() picks a route without sending any packets.
|
||||||
|
try:
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||||
|
s.connect(("8.8.8.8", 80))
|
||||||
|
ip = s.getsockname()[0]
|
||||||
|
if ip and not ip.startswith("127."):
|
||||||
|
return ip
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 3. Give up and use the configured access-point default.
|
||||||
|
return app.config['BUTTERBOX_DEFAULT_IP']
|
||||||
|
|
||||||
def run_madmail_installer():
|
def run_madmail_installer():
|
||||||
with open("./settings.txt", "r") as f:
|
with open("./settings.txt", "r") as f:
|
||||||
settings = json.load(f)
|
settings = json.load(f)
|
||||||
|
|
@ -18,7 +46,7 @@ def run_madmail_installer():
|
||||||
child.expect("MX record")
|
child.expect("MX record")
|
||||||
child.sendline(f"{butterbox_hostname}.local")
|
child.sendline(f"{butterbox_hostname}.local")
|
||||||
child.expect("Public IP address")
|
child.expect("Public IP address")
|
||||||
child.sendline(app.config['BUTTERBOX_DEFAULT_IP'])
|
child.sendline(resolve_butterbox_ip(butterbox_hostname))
|
||||||
child.expect("Additional domains")
|
child.expect("Additional domains")
|
||||||
child.sendline("")
|
child.sendline("")
|
||||||
child.expect("State directory")
|
child.expect("State directory")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue