1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2025-04-29 04:17:07 +00:00

sync with upstream

This commit is contained in:
seanwatson 2017-03-08 20:58:24 -08:00
commit 61fb73ee23
No known key found for this signature in database
GPG Key ID: C91AF2FA988EAF6D
12 changed files with 67 additions and 18 deletions

View File

@ -14,6 +14,13 @@ In Development
* Added support for DSA and ED25519 SSHFP records. * Added support for DSA and ED25519 SSHFP records.
* Added support for custom SSHFP records. * Added support for custom SSHFP records.
v0.21c (February 1, 2017)
-------------------------
Installations and upgrades started failing about 10 days ago with the error "ImportError: No module named 'packaging'" after an upstream package (Python's setuptools) was updated by its maintainers. The updated package conflicted with Ubuntu 14.04's version of another package (Python's pip). This update upgrades both packages to remove the conflict.
If you already encountered the error during installation or upgrade of Mail-in-a-Box, this update may not correct the problem on your existing system. See https://discourse.mailinabox.email/t/v0-21c-release-fixes-python-package-installation-issue/1881 for help if the problem persists after upgrading to this version of Mail-in-a-Box.
v0.21b (December 4, 2016) v0.21b (December 4, 2016)
------------------------- -------------------------

View File

@ -59,7 +59,7 @@ by me:
$ curl -s https://keybase.io/joshdata/key.asc | gpg --import $ curl -s https://keybase.io/joshdata/key.asc | gpg --import
gpg: key C10BDD81: public key "Joshua Tauberer <jt@occams.info>" imported gpg: key C10BDD81: public key "Joshua Tauberer <jt@occams.info>" imported
$ git verify-tag v0.21b $ git verify-tag v0.21c
gpg: Signature made ..... using RSA key ID C10BDD81 gpg: Signature made ..... using RSA key ID C10BDD81
gpg: Good signature from "Joshua Tauberer <jt@occams.info>" gpg: Good signature from "Joshua Tauberer <jt@occams.info>"
gpg: WARNING: This key is not certified with a trusted signature! gpg: WARNING: This key is not certified with a trusted signature!
@ -72,7 +72,7 @@ and on my [personal homepage](https://razor.occams.info/). (Of course, if this r
Checkout the tag corresponding to the most recent release: Checkout the tag corresponding to the most recent release:
$ git checkout v0.21b $ git checkout v0.21c
Begin the installation. Begin the installation.

View File

@ -73,6 +73,7 @@ action = iptables-allports[name=recidive]
enabled = true enabled = true
[ssh] [ssh]
enabled = true
maxretry = 7 maxretry = 7
bantime = 3600 bantime = 3600

View File

@ -39,6 +39,8 @@ def backup_status(env):
def reldate(date, ref, clip): def reldate(date, ref, clip):
if ref < date: return clip if ref < date: return clip
rd = dateutil.relativedelta.relativedelta(ref, date) rd = dateutil.relativedelta.relativedelta(ref, date)
if rd.years > 1: return "%d years, %d months" % (rd.years, rd.months)
if rd.years == 1: return "%d year, %d months" % (rd.years, rd.months)
if rd.months > 1: return "%d months, %d days" % (rd.months, rd.days) if rd.months > 1: return "%d months, %d days" % (rd.months, rd.days)
if rd.months == 1: return "%d month, %d days" % (rd.months, rd.days) if rd.months == 1: return "%d month, %d days" % (rd.months, rd.days)
if rd.days >= 7: return "%d days" % rd.days if rd.days >= 7: return "%d days" % rd.days

View File

@ -599,8 +599,8 @@ def validate_password(pw):
raise ValueError("No password provided.") raise ValueError("No password provided.")
if re.search(r"[\s]", pw): if re.search(r"[\s]", pw):
raise ValueError("Passwords cannot contain spaces.") raise ValueError("Passwords cannot contain spaces.")
if len(pw) < 4: if len(pw) < 8:
raise ValueError("Passwords must be at least four characters.") raise ValueError("Passwords must be at least eight characters.")
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -31,7 +31,7 @@
<button type="submit" class="btn btn-primary">Add User</button> <button type="submit" class="btn btn-primary">Add User</button>
</form> </form>
<ul style="margin-top: 1em; padding-left: 1.5em; font-size: 90%;"> <ul style="margin-top: 1em; padding-left: 1.5em; font-size: 90%;">
<li>Passwords must be at least four characters and may not contain spaces. For best results, <a href="#" onclick="return generate_random_password()">generate a random password</a>.</li> <li>Passwords must be at least eight characters and may not contain spaces. For best results, <a href="#" onclick="return generate_random_password()">generate a random password</a>.</li>
<li>Use <a href="#" onclick="return show_panel('aliases')">aliases</a> to create email addresses that forward to existing accounts.</li> <li>Use <a href="#" onclick="return show_panel('aliases')">aliases</a> to create email addresses that forward to existing accounts.</li>
<li>Administrators get access to this control panel.</li> <li>Administrators get access to this control panel.</li>
<li>User accounts cannot contain any international (non-ASCII) characters, but <a href="#" onclick="return show_panel('aliases');">aliases</a> can.</li> <li>User accounts cannot contain any international (non-ASCII) characters, but <a href="#" onclick="return show_panel('aliases');">aliases</a> can.</li>
@ -296,7 +296,7 @@ function mod_priv(elem, add_remove) {
function generate_random_password() { function generate_random_password() {
var pw = ""; var pw = "";
var charset = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789"; // confusable characters skipped var charset = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789"; // confusable characters skipped
for (var i = 0; i < 10; i++) for (var i = 0; i < 12; i++)
pw += charset.charAt(Math.floor(Math.random() * charset.length)); pw += charset.charAt(Math.floor(Math.random() * charset.length));
show_modal_error("Random Password", "<p>Here, try this:</p> <p><code style='font-size: 110%'>" + pw + "</code></pr"); show_modal_error("Random Password", "<p>Here, try this:</p> <p><code style='font-size: 110%'>" + pw + "</code></pr");
return false; // cancel click return false; // cancel click

View File

@ -7,7 +7,7 @@
######################################################### #########################################################
if [ -z "$TAG" ]; then if [ -z "$TAG" ]; then
TAG=v0.21b TAG=v0.21c
fi fi
# Are we running as root? # Are we running as root?

View File

@ -37,8 +37,16 @@ apt_install \
# of active IMAP connections (at, say, 5 open connections per user that # of active IMAP connections (at, say, 5 open connections per user that
# would be 20 users). Set it to 250 times the number of cores this # would be 20 users). Set it to 250 times the number of cores this
# machine has, so on a two-core machine that's 500 processes/100 users). # machine has, so on a two-core machine that's 500 processes/100 users).
# The `default_vsz_limit` is the maximum amount of virtual memory that
# can be allocated. It should be set *reasonably high* to avoid allocation
# issues with larger mailboxes. We're setting it to 1/3 of the total
# available memory (physical mem + swap) to be sure.
# See here for discussion:
# - https://www.dovecot.org/list/dovecot/2012-August/137569.html
# - https://www.dovecot.org/list/dovecot/2011-December/132455.html
tools/editconf.py /etc/dovecot/conf.d/10-master.conf \ tools/editconf.py /etc/dovecot/conf.d/10-master.conf \
default_process_limit=$(echo "`nproc` * 250" | bc) \ default_process_limit=$(echo "`nproc` * 250" | bc) \
default_vsz_limit=$(echo "`free -tom | tail -1 | awk '{print $2}'` / 3" | bc)M \
log_path=/var/log/mail.log log_path=/var/log/mail.log
# The inotify `max_user_instances` default is 128, which constrains # The inotify `max_user_instances` default is 128, which constrains

View File

@ -4,7 +4,10 @@ source setup/functions.sh
echo "Installing Mail-in-a-Box system management daemon..." echo "Installing Mail-in-a-Box system management daemon..."
# Install packages. # DEPENDENCIES
# Install Python packages that are available from the Ubuntu
# apt repository:
# flask, yaml, dnspython, and dateutil are all for our Python 3 management daemon itself. # flask, yaml, dnspython, and dateutil are all for our Python 3 management daemon itself.
# duplicity does backups. python-pip is so we can 'pip install boto' for Python 2, for duplicity, so it can do backups to AWS S3. # duplicity does backups. python-pip is so we can 'pip install boto' for Python 2, for duplicity, so it can do backups to AWS S3.
apt_install python3-flask links duplicity libyaml-dev python3-dnspython python3-dateutil python-pip apt_install python3-flask links duplicity libyaml-dev python3-dnspython python3-dateutil python-pip
@ -12,17 +15,45 @@ apt_install python3-flask links duplicity libyaml-dev python3-dnspython python3-
# These are required to pip install cryptography. # These are required to pip install cryptography.
apt_install build-essential libssl-dev libffi-dev python3-dev apt_install build-essential libssl-dev libffi-dev python3-dev
# pip<6.1 + setuptools>=34 have a problem with packages that
# try to update setuptools during installation, like cryptography.
# See https://github.com/pypa/pip/issues/4253. The Ubuntu 14.04
# package versions are pip 1.5.4 and setuptools 3.3. When we
# install cryptography under those versions, it tries to update
# setuptools to version 34, which now creates the conflict, and
# then pip gets permanently broken with errors like
# "ImportError: No module named 'packaging'".
#
# Let's test for the error:
if ! python3 -c "from pkg_resources import load_entry_point" 2&> /dev/null; then
# This system seems to be broken already.
echo "Fixing broken pip and setuptools..."
rm -rf /usr/local/lib/python3.4/dist-packages/{pkg_resources,setuptools}*
apt-get install --reinstall python3-setuptools python3-pip python3-pkg-resources
fi
#
# The easiest work-around on systems that aren't already broken is
# to upgrade pip (to >=9.0.1) and setuptools (to >=34.1) individually
# before we install any package that tries to update setuptools.
hide_output pip3 install --upgrade pip
hide_output pip3 install --upgrade setuptools
# Install other Python 3 packages used by the management daemon. # Install other Python 3 packages used by the management daemon.
# The first line is the packages that Josh maintains himself! # The first line is the packages that Josh maintains himself!
# NOTE: email_validator is repeated in setup/questions.sh, so please keep the versions synced. # NOTE: email_validator is repeated in setup/questions.sh, so please keep the versions synced.
# Force acme to be updated because it seems to need it after the
# pip/setuptools breakage (see above) and the ACME protocol may
# have changed (I got an error on one of my systems).
hide_output pip3 install --upgrade \ hide_output pip3 install --upgrade \
rtyaml "email_validator>=1.0.0" "free_tls_certificates>=0.1.3" "exclusiveprocess" \ rtyaml "email_validator>=1.0.0" "free_tls_certificates>=0.1.3" "exclusiveprocess" \
"idna>=2.0.0" "cryptography>=1.0.2" boto psutil "idna>=2.0.0" "cryptography>=1.0.2" acme boto psutil
# duplicity uses python 2 so we need to get the python 2 package of boto to have backups to S3. # duplicity uses python 2 so we need to get the python 2 package of boto to have backups to S3.
# boto from the Ubuntu package manager is too out-of-date -- it doesn't support the newer # boto from the Ubuntu package manager is too out-of-date -- it doesn't support the newer
# S3 api used in some regions, which breaks backups to those regions. See #627, #653. # S3 api used in some regions, which breaks backups to those regions. See #627, #653.
hide_output pip install --upgrade boto hide_output pip2 install --upgrade boto
# CONFIGURATION
# Create a backup directory and a random key for encrypting backups. # Create a backup directory and a random key for encrypting backups.
mkdir -p $STORAGE_ROOT/backup mkdir -p $STORAGE_ROOT/backup

View File

@ -147,17 +147,17 @@ if management/status_checks.py --check-primary-hostname; then
echo https://$PRIMARY_HOSTNAME/admin echo https://$PRIMARY_HOSTNAME/admin
echo echo
echo "If you have a DNS problem put the box's IP address in the URL" echo "If you have a DNS problem put the box's IP address in the URL"
echo "(https://$PUBLIC_IP/admin) but then check the SSL fingerprint:" echo "(https://$PUBLIC_IP/admin) but then check the TLS fingerprint:"
openssl x509 -in $STORAGE_ROOT/ssl/ssl_certificate.pem -noout -fingerprint \ openssl x509 -in $STORAGE_ROOT/ssl/ssl_certificate.pem -noout -fingerprint -sha256\
| sed "s/SHA1 Fingerprint=//" | sed "s/SHA256 Fingerprint=//"
else else
echo https://$PUBLIC_IP/admin echo https://$PUBLIC_IP/admin
echo echo
echo You will be alerted that the website has an invalid certificate. Check that echo You will be alerted that the website has an invalid certificate. Check that
echo the certificate fingerprint matches: echo the certificate fingerprint matches:
echo echo
openssl x509 -in $STORAGE_ROOT/ssl/ssl_certificate.pem -noout -fingerprint \ openssl x509 -in $STORAGE_ROOT/ssl/ssl_certificate.pem -noout -fingerprint -sha256\
| sed "s/SHA1 Fingerprint=//" | sed "s/SHA256 Fingerprint=//"
echo echo
echo Then you can confirm the security exception and continue. echo Then you can confirm the security exception and continue.
echo echo

View File

@ -185,7 +185,7 @@ cp ${RCM_PLUGIN_DIR}/password/config.inc.php.dist \
${RCM_PLUGIN_DIR}/password/config.inc.php ${RCM_PLUGIN_DIR}/password/config.inc.php
tools/editconf.py ${RCM_PLUGIN_DIR}/password/config.inc.php \ tools/editconf.py ${RCM_PLUGIN_DIR}/password/config.inc.php \
"\$config['password_minimum_length']=6;" \ "\$config['password_minimum_length']=8;" \
"\$config['password_db_dsn']='sqlite:///$STORAGE_ROOT/mail/users.sqlite';" \ "\$config['password_db_dsn']='sqlite:///$STORAGE_ROOT/mail/users.sqlite';" \
"\$config['password_query']='UPDATE users SET password=%D WHERE email=%u';" \ "\$config['password_query']='UPDATE users SET password=%D WHERE email=%u';" \
"\$config['password_dovecotpw']='/usr/bin/doveadm pw';" \ "\$config['password_dovecotpw']='/usr/bin/doveadm pw';" \

View File

@ -30,8 +30,8 @@ def mgmt(cmd, data=None, is_json=False):
def read_password(): def read_password():
while True: while True:
first = getpass.getpass('password: ') first = getpass.getpass('password: ')
if len(first) < 4: if len(first) < 8:
print("Passwords must be at least four characters.") print("Passwords must be at least eight characters.")
continue continue
if re.search(r'[\s]', first): if re.search(r'[\s]', first):
print("Passwords cannot contain spaces.") print("Passwords cannot contain spaces.")