From 9ee26d3ef101b3a393738aca1afdc8259d23020f Mon Sep 17 00:00:00 2001 From: KiekerJan Date: Sat, 17 Sep 2022 16:41:35 +0200 Subject: [PATCH] merge upstream changes proposed for 2204 --- CHANGELOG.md | 8 +++++++- conf/mailinabox.service | 1 + management/auth.py | 16 ++-------------- management/backup.py | 2 +- management/daemon.py | 4 ++-- management/templates/system-backup.html | 1 + management/wsgi.py | 7 +++++++ setup/bootstrap.sh | 6 +----- setup/management.sh | 10 ++++++++-- setup/nextcloud.sh | 3 --- setup/preflight.sh | 6 +++--- setup/webmail.sh | 13 ++++++++----- tools/editconf.py | 5 +++-- 13 files changed, 44 insertions(+), 38 deletions(-) create mode 100644 management/wsgi.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 533a556c..c50a3b15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,12 +15,18 @@ LINK TBD No features of Mail-in-a-Box have changed in this release, but with the newer version of Ubuntu the following software packages we use are updated: * dovecot is upgraded to 2.3.16, postfix to 3.6.4, opendmark to 1.4 (which adds ARC-Authentication-Results headers), and spampd to 2.53 (alleviating a mail delivery rate limiting bug). -* Nextcloud is upgraded to 24.0.0 with PHP updated from 7.2 to 8.1. +* Nextcloud is upgraded to 24.0.0 +* Roundcube is upgraded to 1.6.0. * certbot is upgraded to 1.21 (via the Ubuntu repository instead of a PPA). * fail2ban is upgraded to 0.11.2. * nginx is upgraded to 1.18. +* PHP is upgraded from 7.2 to 8.1. * bind9 is replaced with unbound +Also: + +* Roundcube's login session cookie was tightened. Existing sessions may require a manual logout. + Version 57a (June 19, 2022) --------------------------- diff --git a/conf/mailinabox.service b/conf/mailinabox.service index b4cfa6cf..c1d98a03 100644 --- a/conf/mailinabox.service +++ b/conf/mailinabox.service @@ -4,6 +4,7 @@ After=multi-user.target [Service] Type=idle +IgnoreSIGPIPE=False ExecStart=/usr/local/lib/mailinabox/start [Install] diff --git a/management/auth.py b/management/auth.py index 0a88c457..c576d01c 100644 --- a/management/auth.py +++ b/management/auth.py @@ -22,20 +22,8 @@ class AuthService: def init_system_api_key(self): """Write an API key to a local file so local processes can use the API""" - def create_file_with_mode(path, mode): - # Based on answer by A-B-B: http://stackoverflow.com/a/15015748 - old_umask = os.umask(0) - try: - return os.fdopen(os.open(path, os.O_WRONLY | os.O_CREAT, mode), 'w') - finally: - os.umask(old_umask) - - self.key = secrets.token_hex(32) - - os.makedirs(os.path.dirname(self.key_path), exist_ok=True) - - with create_file_with_mode(self.key_path, 0o640) as key_file: - key_file.write(self.key + '\n') + with open(self.key_path, 'r') as file: + self.key = file.read() def authenticate(self, request, env, login_only=False, logout=False): """Test if the HTTP Authorization header's username matches the system key, a session key, diff --git a/management/backup.py b/management/backup.py index 4887c662..0c30b83e 100755 --- a/management/backup.py +++ b/management/backup.py @@ -463,7 +463,7 @@ def list_target_files(config): path = '' if bucket == "": - raise ValueError(f"Enter an S3 bucket name. // {url}") + raise ValueError("Enter an S3 bucket name.") # connect to the region & bucket try: diff --git a/management/daemon.py b/management/daemon.py index 54275fd9..97145994 100755 --- a/management/daemon.py +++ b/management/daemon.py @@ -123,8 +123,8 @@ def index(): no_admins_exist = (len(get_admins(env)) == 0) import boto3.s3 - from urllib.parse import urlparse - backup_s3_hosts = [(r, urlparse(boto3.client('s3', region_name=r).meta.endpoint_url).netloc) for r in boto3.session.Session().get_available_regions('s3')] + backup_s3_hosts = [(r, f"s3.{r}.amazonaws.com") for r in boto3.session.Session().get_available_regions('s3')] + return render_template('index.html', hostname=env['PRIMARY_HOSTNAME'], diff --git a/management/templates/system-backup.html b/management/templates/system-backup.html index 3075b912..5450b6e5 100644 --- a/management/templates/system-backup.html +++ b/management/templates/system-backup.html @@ -269,6 +269,7 @@ function show_custom_backup() { $("#backup-target-type").val("s3"); var hostpath = r.target.substring(5).split('/'); var host = hostpath.shift(); + $("#backup-target-s3-host-select").val(host); $("#backup-target-s3-host").val(host); $("#backup-target-s3-path").val(hostpath.join('/')); } else if (r.target.substring(0, 5) == "b2://") { diff --git a/management/wsgi.py b/management/wsgi.py new file mode 100644 index 00000000..86cf3af4 --- /dev/null +++ b/management/wsgi.py @@ -0,0 +1,7 @@ +from daemon import app +import auth, utils + +app.logger.addHandler(utils.create_syslog_handler()) + +if __name__ == "__main__": + app.run(port=10222) \ No newline at end of file diff --git a/setup/bootstrap.sh b/setup/bootstrap.sh index 4df85ca5..3da667a2 100644 --- a/setup/bootstrap.sh +++ b/setup/bootstrap.sh @@ -26,10 +26,6 @@ if [ -z "$TAG" ]; then # This machine is running Ubuntu 22.04, which is supported by # Mail-in-a-Box versions 60 and later. TAG=v60 - elif [ "$UBUNTU_VERSION" == "Ubuntu 20.04 LTS" ]; then - # This machine is running Ubuntu 20.04, which is supported by - # Mail-in-a-Box versions 56 and later. - TAG=v57a elif [ "$UBUNTU_VERSION" == "Ubuntu 18.04 LTS" ]; then # This machine is running Ubuntu 18.04, which is supported by # Mail-in-a-Box versions 0.40 through 5x. @@ -46,7 +42,7 @@ if [ -z "$TAG" ]; then echo "The last version of Mail-in-a-Box supporting Ubuntu 14.04 will be installed." TAG=v0.30 else - echo "This script may be used only on a machine running Ubuntu 14.04, 18.04, 20.04 or 22.04." + echo "This script may be used only on a machine running Ubuntu 14.04, 18.04, or 22.04." exit 1 fi fi diff --git a/setup/management.sh b/setup/management.sh index cfac5db9..cebed8d5 100755 --- a/setup/management.sh +++ b/setup/management.sh @@ -50,7 +50,7 @@ hide_output $venv/bin/pip install --upgrade pip # NOTE: email_validator is repeated in setup/questions.sh, so please keep the versions synced. hide_output $venv/bin/pip install --upgrade \ rtyaml "email_validator>=1.0.0" "exclusiveprocess" \ - flask dnspython python-dateutil expiringdict \ + flask dnspython python-dateutil expiringdict gunicorn \ qrcode[pil] pyotp \ "idna>=2.0.0" "cryptography==37.0.2" psutil postfix-mta-sts-resolver \ b2sdk boto3 @@ -90,6 +90,7 @@ rm -f /tmp/bootstrap.zip # Create an init script to start the management daemon and keep it # running after a reboot. +# Note: Authentication currently breaks with more than 1 gunicorn worker. cat > $inst_dir/start < /var/lib/mailinabox/api.key +chmod 640 /var/lib/mailinabox/api.key + source $venv/bin/activate -exec python $(pwd)/management/daemon.py +export PYTHONPATH=$(pwd)/management +exec gunicorn -b localhost:10222 -w 1 wsgi:app EOF chmod +x $inst_dir/start cp --remove-destination conf/mailinabox.service /lib/systemd/system/mailinabox.service # target was previously a symlink so remove it first diff --git a/setup/nextcloud.sh b/setup/nextcloud.sh index 49b536bc..1cec5fda 100755 --- a/setup/nextcloud.sh +++ b/setup/nextcloud.sh @@ -386,9 +386,6 @@ cat > /etc/cron.d/mailinabox-nextcloud << EOF; EOF chmod +x /etc/cron.d/mailinabox-nextcloud -# Remove previous hourly cronjob -rm -f /etc/cron.hourly/mailinabox-owncloud - # There's nothing much of interest that a user could do as an admin for Nextcloud, # and there's a lot they could mess up, so we don't make any users admins of Nextcloud. # But if we wanted to, we would do this: diff --git a/setup/preflight.sh b/setup/preflight.sh index 83b7c1bd..e921f298 100644 --- a/setup/preflight.sh +++ b/setup/preflight.sh @@ -7,9 +7,9 @@ if [[ $EUID -ne 0 ]]; then exit 1 fi -# Check that we are running on Ubuntu 20.04 LTS or Ubuntu 22.04 LTS -if [ "$( lsb_release --id --short )" != "Ubuntu" ] || [ "$( lsb_release --release --short )" != "22.04" -a "$( lsb_release --release --short )" != "20.04" ]; then - echo "Mail-in-a-Box only supports being installed on Ubuntu 20.04 or 22.04, sorry. You are running:" +# Check that we are running on Ubuntu 22.04 LTS (or 22.04.xx). +if [ "$( lsb_release --id --short )" != "Ubuntu" ] || [ "$( lsb_release --release --short )" != "22.04" ]; then + echo "Mail-in-a-Box only supports being installed on Ubuntu 22.04, sorry. You are running:" echo lsb_release --description --short echo diff --git a/setup/webmail.sh b/setup/webmail.sh index 57dc32fa..0ac6055d 100755 --- a/setup/webmail.sh +++ b/setup/webmail.sh @@ -22,7 +22,7 @@ source /etc/mailinabox.conf # load global vars echo "Installing Roundcube (webmail)..." apt_install \ dbconfig-common \ - php-cli php-sqlite3 php-intl php-json php-common php-curl php-ldap \ + php-cli php-sqlite3 php-intl php-json php-common php-curl php-imap \ php-gd php-pspell libjs-jquery libjs-jquery-mousewheel libmagic1 php-mbstring # Install Roundcube from source if it is not already present or if it is out of date. @@ -124,8 +124,7 @@ cat > $RCM_CONFIG < array( 'verify_peer' => false, @@ -133,7 +132,7 @@ cat > $RCM_CONFIG < array( 'verify_peer' => false, @@ -150,6 +149,10 @@ cat > $RCM_CONFIG < EOF @@ -216,5 +219,5 @@ chown www-data:www-data $STORAGE_ROOT/mail/roundcube/roundcube.sqlite chmod 664 $STORAGE_ROOT/mail/roundcube/roundcube.sqlite # Enable PHP modules. -phpenmod -v php mcrypt imap +phpenmod -v php imap restart_service php$PHP_VER-fpm diff --git a/tools/editconf.py b/tools/editconf.py index e80742e4..dc184966 100755 --- a/tools/editconf.py +++ b/tools/editconf.py @@ -136,9 +136,10 @@ while len(input_lines) > 0: # Put any settings we didn't see at the end of the file, # except settings being cleared. for i in range(len(settings)): - if (i not in found) and not (not val and erase_setting): + if i not in found: name, val = settings[i].split("=", 1) - buf += name + delimiter + val + "\n" + if not (not val and erase_setting): + buf += name + delimiter + val + "\n" if not testing: # Write out the new file.