From e37768ca8680106b037822975445de88e3e0da14 Mon Sep 17 00:00:00 2001
From: Joshua Tauberer <jt@occams.info>
Date: Sat, 3 Aug 2019 11:49:32 -0400
Subject: [PATCH 1/6] v0.42b

---
 CHANGELOG.md       | 6 ++++--
 README.md          | 4 ++--
 setup/bootstrap.sh | 2 +-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 15311c84..a07304b6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,8 @@
 CHANGELOG
 =========
 
-v0.42 (July 4, 2019)
---------------------
+v0.42b (August 3, 2019)
+-----------------------
 
 Changes:
 
@@ -19,6 +19,8 @@ Software updates:
 * Upgraded Nextcloud from 14.0.6 to 15.0.8 (with Contacts from 2.1.8 to 3.1.1 and Calendar from 1.6.4 to 1.6.5).
 * Upgraded Z-Push from 2.4.4 to 2.5.0.
 
+Note that v0.42 (July 4, 2019) was pulled shortly after it was released to fix a Nextcloud upgrade issue.
+
 v0.41 (February 26, 2019)
 -------------------------
 
diff --git a/README.md b/README.md
index d93a0847..925e62aa 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ by him:
 	$ curl -s https://keybase.io/joshdata/key.asc | gpg --import
 	gpg: key C10BDD81: public key "Joshua Tauberer <jt@occams.info>" imported
 
-	$ git verify-tag v0.42
+	$ git verify-tag v0.42b
 	gpg: Signature made ..... using RSA key ID C10BDD81
 	gpg: Good signature from "Joshua Tauberer <jt@occams.info>"
 	gpg: WARNING: This key is not certified with a trusted signature!
@@ -71,7 +71,7 @@ and on his [personal homepage](https://razor.occams.info/). (Of course, if this
 
 Checkout the tag corresponding to the most recent release:
 
-	$ git checkout v0.42
+	$ git checkout v0.42b
 
 Begin the installation.
 
diff --git a/setup/bootstrap.sh b/setup/bootstrap.sh
index 74bf5e16..1135107b 100644
--- a/setup/bootstrap.sh
+++ b/setup/bootstrap.sh
@@ -20,7 +20,7 @@ if [ -z "$TAG" ]; then
 	# want to display in status checks.
 	if [ "`lsb_release -d | sed 's/.*:\s*//' | sed 's/18\.04\.[0-9]/18.04/' `" == "Ubuntu 18.04 LTS" ]; then
 		# This machine is running Ubuntu 18.04.
-		TAG=v0.41
+		TAG=v0.42b
 
 	elif [ "`lsb_release -d | sed 's/.*:\s*//' | sed 's/14\.04\.[0-9]/14.04/' `" == "Ubuntu 14.04 LTS" ]; then
 		# This machine is running Ubuntu 14.04.

From 0657f9e875895adbc46cb36b72c6aa3f55a88e45 Mon Sep 17 00:00:00 2001
From: captainwasabi <captainwasabi@users.noreply.github.com>
Date: Tue, 13 Aug 2019 05:47:11 -0400
Subject: [PATCH 2/6] add proper check for DNS error in list_target_files
 (#1625)

The elif needed to check to see if the string was in the listing of results of the shell command.  As it was the conditional was just the string which always evaluates to true and was therefore giving a misleading error message.
---
 management/backup.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/management/backup.py b/management/backup.py
index 93136bf5..cd1ee6fc 100755
--- a/management/backup.py
+++ b/management/backup.py
@@ -406,7 +406,7 @@ def list_target_files(config):
 				reason = "Provided path {} is invalid.".format(target_path)
 			elif 'Network is unreachable' in listing:
 				reason = "The IP address {} is unreachable.".format(target.hostname)
-			elif 'Could not resolve hostname':
+			elif 'Could not resolve hostname' in listing:
 				reason = "The hostname {} cannot be resolved.".format(target.hostname)
 			else:
 				reason = "Unknown error." \

From c4cb828f6562ad03497e64acd2ebb0af7294d36c Mon Sep 17 00:00:00 2001
From: captainwasabi <captainwasabi@users.noreply.github.com>
Date: Tue, 13 Aug 2019 05:57:05 -0400
Subject: [PATCH 3/6] Fix rsync backup options string: extraneous single quotes
 causing problems (#1629)

The resulting command had nested single quotes which doesn't work

I think this fixes all/most of the issues in #1627.  I am getting a full backup, then the next time it's run I get an incremental.  running from the CLI with --status looks good, --verify looks good, and --list looks good.
---
 management/backup.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/management/backup.py b/management/backup.py
index cd1ee6fc..11cdbb8a 100755
--- a/management/backup.py
+++ b/management/backup.py
@@ -15,8 +15,8 @@ from exclusiveprocess import Lock
 from utils import load_environment, shell, wait_for_service, fix_boto
 
 rsync_ssh_options = [
-	"--ssh-options='-i /root/.ssh/id_rsa_miab'",
-	"--rsync-options=-e \"/usr/bin/ssh -oStrictHostKeyChecking=no -oBatchMode=yes -p 22 -i /root/.ssh/id_rsa_miab\"",
+	"--ssh-options= -i /root/.ssh/id_rsa_miab",
+	"--rsync-options= -e \"/usr/bin/ssh -oStrictHostKeyChecking=no -oBatchMode=yes -p 22 -i /root/.ssh/id_rsa_miab\"",
 ]
 
 def backup_status(env):

From 295d481603025a603e3f39cb8da8629ba569f98f Mon Sep 17 00:00:00 2001
From: cmharper <1422608+cmharper@users.noreply.github.com>
Date: Sat, 31 Aug 2019 11:55:38 +0000
Subject: [PATCH 4/6] Upgraded roundcube to 1.3.10 (#1634)

---
 setup/webmail.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/setup/webmail.sh b/setup/webmail.sh
index cbe6bfca..6cbe55f9 100755
--- a/setup/webmail.sh
+++ b/setup/webmail.sh
@@ -28,8 +28,8 @@ apt_install \
 # Install Roundcube from source if it is not already present or if it is out of date.
 # Combine the Roundcube version number with the commit hash of plugins to track
 # whether we have the latest version of everything.
-VERSION=1.3.9
-HASH=02850972b416bbfa1c13580f16d06fd7ae2774aa
+VERSION=1.3.10
+HASH=431625fc737e301f9b7e502cccc61e50a24786b8
 PERSISTENT_LOGIN_VERSION=dc5ca3d3f4415cc41edb2fde533c8a8628a94c76
 HTML5_NOTIFIER_VERSION=4b370e3cd60dabd2f428a26f45b677ad1b7118d5
 CARDDAV_VERSION=3.0.3

From 08021ea19f1a5395d09e2bc557cbf8b5cdef18d4 Mon Sep 17 00:00:00 2001
From: Snacho <i@sasha.moe>
Date: Sat, 31 Aug 2019 14:58:12 +0300
Subject: [PATCH 5/6] Fix an issue when Secondary NS has multiple A records
 (#1633)

If a custom secondary NS server has multiple A records status_checks.py will fail with a timeout and Web UI won't load.
---
 management/status_checks.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/management/status_checks.py b/management/status_checks.py
index 6f9bb1ef..a9d0595c 100755
--- a/management/status_checks.py
+++ b/management/status_checks.py
@@ -486,10 +486,12 @@ def check_dns_zone(domain, env, output, dns_zonefiles):
 	if custom_secondary_ns and not probably_external_dns:
 		for ns in custom_secondary_ns:
 			# We must first resolve the nameserver to an IP address so we can query it.
-			ns_ip = query_dns(ns, "A")
-			if not ns_ip:
+			ns_ips = query_dns(ns, "A")
+			if not ns_ips:
 				output.print_error("Secondary nameserver %s is not valid (it doesn't resolve to an IP address)." % ns)
 				continue
+			# Choose the first IP if nameserver returns multiple
+			ns_ip = ns_ips.split('; ')[0]
 
 			# Now query it to see what it says about this domain.
 			ip = query_dns(domain, "A", at=ns_ip, nxdomain=None)

From c7377e602d06a792b97a5a1047bbdeb32bdd377a Mon Sep 17 00:00:00 2001
From: Kim Schulz <kim@schulz.dk>
Date: Sat, 31 Aug 2019 14:00:18 +0200
Subject: [PATCH 6/6] make it possible to use subnet addresses for axfr (#1616)

it is sometimes needed to be able to set axfr to more than just one ip address. This can be done with multiple xfr: in  the secondary dns input but if you need to add an entire subnet segment (xxx.xxx.xxx.0/yy) then it will not work.
With this patch it is now possible to use a subnet as input for xfr the same way as if it was an ip address.
---
 management/dns_update.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/management/dns_update.py b/management/dns_update.py
index 7e006d0b..7eed50b5 100755
--- a/management/dns_update.py
+++ b/management/dns_update.py
@@ -903,8 +903,12 @@ def set_secondary_dns(hostnames, env):
 			else:
 				# Validate IP address.
 				try:
-					v = ipaddress.ip_address(item[4:]) # raises a ValueError if there's a problem
-					if not isinstance(v, ipaddress.IPv4Address): raise ValueError("That's an IPv6 address.")
+                    if "/" in item[4:]:
+                        v = ipaddress.ip_network(item[4:] # raises a ValueError if there's a problem
+                        if not isinstance(v, ipaddress.IPv4Network): raise ValueError("That's an IPv6 subnet.")
+                    else:
+					    v = ipaddress.ip_address(item[4:]) # raises a ValueError if there's a problem
+					    if not isinstance(v, ipaddress.IPv4Address): raise ValueError("That's an IPv6 address.")
 				except ValueError:
 					raise ValueError("'%s' is not an IPv4 address." % item[4:])