Recent changes to this wiki:

LE supports wildcard now?
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 20ae63d..ecab24a 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -191,6 +191,8 @@ previously mentioned. --[[anarcat]]
  [lego]: https://github.com/xenolf/lego
 
 
+Note that Let's Encrypt started [supporting wildcard certificates](https://arstechnica.com/information-technology/2017/07/lets-encrypt-to-start-offering-free-wildcard-certificates-for-https/) recently, but only with DNS challenges.. --[[anarcat]]
+
 ---- 
 
 ## how to only enable ssl once a certificate is available

add lego because it supports DNS challenges
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index b2d285d..20ae63d 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -64,6 +64,7 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
  * [simp_le][], much simpler implementation in Python ([not in Debian](https://github.com/kuba/simp_le/issues/69))
  * [acme][], root-less, more minimal implementation than the official
    client, in Go ([in Debian stretch and sid](https://tracker.debian.org/pkg/acmetool))
+ * [lego][], root-less, fairly featureful, also [in Debian](https://tracker.debian.org/pkg/lego)
  * [acme-tiny][] is a very small client (~200 lines of python code)
    that aims to be easily audited and to do only one thing well. for
    example, you need to generate your RSA key yourself, which may
@@ -80,6 +81,7 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
  [acme-tiny]: https://github.com/diafygi/acme-tiny/
  [ITP for acmetool]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=817091
  [in Debian stretch and sid]: https://tracker.debian.org/pkg/acme-tiny
+ [lego]: https://github.com/xenolf/lego
 
 Note that I have also considered simply using the `--apache` plugin to just have LE manage all those certs itself. This could conflict with ikiwiki-hosting, but since it runs fairly frequently, it could just win in the end. It's not a great solution for sites managed by the control panel, but for my use case, it could just work. Unforunately, it [parses configs in sites-available instead of just sites-enabled](https://github.com/certbot/certbot/issues/3545) which breaks it for me. --[[anarcat]]
 

Announce 0.20170622
diff --git a/doc/news/version_0.20170622.mdwn b/doc/news/version_0.20170622.mdwn
new file mode 100644
index 0000000..42aa5bd
--- /dev/null
+++ b/doc/news/version_0.20170622.mdwn
@@ -0,0 +1,20 @@
+ikiwiki-hosting 0.20170622 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+ * [ [[Joey Hess|joey]] ]
+   * remove, letsnotencrypt: Remove Lets Encrypt renewal file, to avoid
+     the cron job trying to renew deleted sites.
+   * Fix deletion of sites that use https over the web interface.
+   * HTTP Strict Transport Security (HSTS) is enabled for all
+     sites that have `redirect_to_https` set in their configuration.
+     Thanks, Antoine Beaupré.
+   * Improve `ikisite backup` to lock the wiki for a much shorter period of time.
+   * Remove `.ikiwiki/sessions.db` from the ikisite backup, as the file can be
+     rather large, and losing it only means users have to log back in sooner
+     than would otherwise be the case.
+   * ikisite-wrapper: Allow `ikisite enable` to be run via the wrapper.
+     The CGI uses this to update the site config of an already enabled site
+     when enabling eg `redirect_to_https` or adding a DNS alias.
+ * [ [[Simon McVittie|smcv]] ]
+   * debian/copyright: Use preferred https URL for Format
+   * debian/control: Declare compliance with Debian Policy 4.0.0
+   * debian: Update to debhelper compat level 10"""]]

ikisite-wrapper: Allow ikisite enable to be run via the wrapper.
The CGI uses this to update the site config of an already enabled site when
enabling eg redirect_to_https or adding a DNS alias.
This commit was sponsored by Jochen Bartl on Patreon.
diff --git a/IkiWiki/Plugin/ikiwikihosting.pm b/IkiWiki/Plugin/ikiwikihosting.pm
index 5c30ed8..5571fb3 100644
--- a/IkiWiki/Plugin/ikiwikihosting.pm
+++ b/IkiWiki/Plugin/ikiwikihosting.pm
@@ -460,11 +460,14 @@ sub handlechangedsetup {
 	# Drop lock; ikisite takes the lock itself.
 	IkiWiki::unlockwiki();
 
-	# If ipv6 was enabled or disabled, need to refresh dns.
-	IkiWiki::Hosting::getshell("ikisite-wrapper", "enabledns", $config{hostname});
-
 	# Commit any changes to the setup file into the setup branch.
 	IkiWiki::Hosting::getshell("ikisite", "commitsetup", $config{hostname});
+
+	# Re-enable the site for changes to eg, redirect_to_https or dns.
+	# This can't enable any site that's not enabled, since the site has
+	# to be enabled already for this cgi to be run.
+	IkiWiki::Hosting::getshell("ikisite-wrapper", "enable", $config{hostname});
+	
 	exit;
 }
 
diff --git a/debian/changelog b/debian/changelog
index 72f895f..e9b4398 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -10,6 +10,9 @@ ikiwiki-hosting (0.20161220) UNRELEASED; urgency=medium
   * Remove .ikiwiki/sessions.db from the ikisite backup, as the file can be
     rather large, and losing it only means users have to log back in sooner
     than would otherwise be the case.
+  * ikisite-wrapper: Allow ikisite enable to be run via the wrapper.
+    The CGI uses this to update the site config of an already enabled site
+    when enabling eg redirect_to_https or adding a DNS alias.
 
  -- Joey Hess <id@joeyh.name>  Wed, 25 Jan 2017 12:35:51 -0400
 
diff --git a/doc/ikisite-wrapper.mdwn b/doc/ikisite-wrapper.mdwn
index 45eb345..39d0f2e 100644
--- a/doc/ikisite-wrapper.mdwn
+++ b/doc/ikisite-wrapper.mdwn
@@ -13,8 +13,8 @@ made suid root, though it is not currently suid by default.
 
 A few ikisite subcommands can be run using the wrapper without any
 authorisation at all. These include: create, branch, list, sitelookup,
-checklock, updatecustomersite, and enabledns. So making the wrapper suid
-allows any user to create a site.
+checklock, updatecustomersite, enabledns, and enable. So making the
+wrapper suid allows any user to create a site.
 
 Other ikisite subcommands can only be run using the wrapper by
 users who specify a nonce in the IKISITE_NONCE environment variable. These
diff --git a/ikisite b/ikisite
index 89c8e13..ac262d7 100755
--- a/ikisite
+++ b/ikisite
@@ -1510,7 +1510,11 @@ sub enable {
 	
 	assert_root();
 	locksite($hostname);
-	assert_wrapper_denied();
+	# Allow the wrapper to enable a site. The CGI for a site uses
+	# this when its configuration is changed; the site is necessarily
+	# already enabled for the CGI to run so this should not let
+	# disabled sites be enabled via the CGI.
+	assert_wrapper_unsafe();
 
 	my $user=username($hostname);
 	my $home=homedir($hostname);
diff --git a/ikisite-wrapper.c b/ikisite-wrapper.c
index 274fff7..a4bde3f 100644
--- a/ikisite-wrapper.c
+++ b/ikisite-wrapper.c
@@ -35,6 +35,7 @@ int main (int argc, char **argv) {
 		    strcmp(argv[1], "updatecustomersite") == 0 ||
 		    strcmp(argv[1], "checksite") == 0 ||
 		    strcmp(argv[1], "enabledns") == 0) {
+		    strcmp(argv[1], "enable") == 0) {
 			/* use a dummy value so ikisite still can tell
 			 * it is being run from the wrapper */
 			nonce="dummy";

HTTP Strict Transport Security (HSTS) is enabled for all sites that have redirect_to_https set in their configuration. Thanks, Antoine Beaupré.
diff --git a/debian/changelog b/debian/changelog
index ab076b7..d79dc65 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,9 @@ ikiwiki-hosting (0.20161220) UNRELEASED; urgency=medium
   * remove, letsnotencrypt: Remove Lets Encrypt renewal file, to avoid
     the cron job trying to renew deleted sites.
   * Fix deletion of sites that use https over the web interface.
+  * HTTP Strict Transport Security (HSTS) is enabled for all
+    sites that have redirect_to_https set in their configuration.
+    Thanks, Antoine Beaupré.
 
  -- Joey Hess <id@joeyh.name>  Wed, 25 Jan 2017 12:35:51 -0400
 
diff --git a/doc/todo/strict_transport_security.mdwn b/doc/todo/strict_transport_security.mdwn
index a832523..8620692 100644
--- a/doc/todo/strict_transport_security.mdwn
+++ b/doc/todo/strict_transport_security.mdwn
@@ -20,3 +20,5 @@ Thanks! --[[anarcat]]
 
 [hsts branch]: https://gitlab.com/anarcat/ikiwiki-hosting/tree/hsts
 [merge it]: https://gitlab.com/anarcat/ikiwiki-hosting/commit/07d443ee33d366c68a57f3d6515ddfbc19147572
+
+> [[merged|done]] --[[Joey]]

some weird issue with the control panel
diff --git a/doc/bugs/controlpanel_crashes_when_ikisite-wrapper_fails.mdwn b/doc/bugs/controlpanel_crashes_when_ikisite-wrapper_fails.mdwn
new file mode 100644
index 0000000..fafbe7e
--- /dev/null
+++ b/doc/bugs/controlpanel_crashes_when_ikisite-wrapper_fails.mdwn
@@ -0,0 +1,41 @@
+If ikisite-wrapper is not suid (which is the default), the command will fail when ran. Or more precisely, it will return nothing.
+
+This will make the following code block crash:
+
+[[!format perl """
+        foreach my $siteinfo (@{IkiWiki::Hosting::yamlgetshell(
+                                  "ikisite-wrapper", "list", "--extended",
+                                  (map { "--admin=$_"} @accounts),
+                                  (map { "--owner=$_"} @accounts),
+                              )}) {
+"""]]
+
+... in controlpanel.pm, because it returns an empty reference. I'm  not sure what to do with this - as I'm not really using the control panel, but I figured this could help:
+
+[[!format diff """
+diff --git a/IkiWiki/Plugin/controlpanel.pm b/IkiWiki/Plugin/controlpanel.pm
+index c55a97d..37981f1 100644
+--- a/IkiWiki/Plugin/controlpanel.pm
++++ b/IkiWiki/Plugin/controlpanel.pm
+@@ -35,11 +35,12 @@ sub sessioncgi ($$) {
+ 
+        my (@owned_sites, @adminned_sites);
+        my $num=0;
+-       foreach my $siteinfo (@{IkiWiki::Hosting::yamlgetshell(
+-                                 "ikisite-wrapper", "list", "--extended",
+-                                 (map { "--admin=$_"} @accounts),
+-                                 (map { "--owner=$_"} @accounts),
+-                             )}) {
++       my $sites = IkiWiki::Hosting::yamlgetshell(
++           "ikisite-wrapper", "list", "--extended",
++           (map { "--admin=$_"} @accounts),
++           (map { "--owner=$_"} @accounts),
++           );
++       foreach my $siteinfo (@{$sites}) {
+                $siteinfo->{cgiurl}=$config{cgiurl};
+                $siteinfo->{num}=$num++;
+ 
+"""]]
+
+
+... no? --[[anarcat]]

HSTS patch
diff --git a/doc/todo/strict_transport_security.mdwn b/doc/todo/strict_transport_security.mdwn
new file mode 100644
index 0000000..a832523
--- /dev/null
+++ b/doc/todo/strict_transport_security.mdwn
@@ -0,0 +1,22 @@
+I noticed a change in my local config during my last ikiwiki-hosting
+upgrade: I had enabled [HSTS][] in my local apache template, to
+prevent downgrade attacks in cases where HTTP to HTTPS redirection is
+enabled.
+
+[HSTS]: https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
+
+The [[patch]] is trivial, and I encourage you to [merge it][] from
+my [hsts branch][]. I used an arbitrary 6-month delay, but would
+welcome comments on better policies... This was a key part in getting
+my site a [better score][] on the [Mozilla SSL Observatory][]. I made
+other changes at the global level on the server configuration, but
+this one is vhost-specific, so I had to roll it out in the Apache
+template. With the changes, I was able to move from a D- score to A-.
+
+[Mozilla SSL Observatory]: https://observatory.mozilla.org/
+[better score]: https://observatory.mozilla.org/analyze.html?host=anarc.at
+
+Thanks! --[[anarcat]]
+
+[hsts branch]: https://gitlab.com/anarcat/ikiwiki-hosting/tree/hsts
+[merge it]: https://gitlab.com/anarcat/ikiwiki-hosting/commit/07d443ee33d366c68a57f3d6515ddfbc19147572

Announce 0.20161219
diff --git a/doc/news/version_0.20161219.mdwn b/doc/news/version_0.20161219.mdwn
new file mode 100644
index 0000000..d0b0de0
--- /dev/null
+++ b/doc/news/version_0.20161219.mdwn
@@ -0,0 +1,16 @@
+ikiwiki-hosting 0.20161219 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+ * [ Joey Hess ]
+   * Initial support for Lets Encrypt.
+   * The use\_letsencrypt setting can be set for a site by running
+     ikisite letsencrypt domain, and it will attempt to get the certificate
+     for it using certbot.
+   * ikisite domains: Update certificate using certbot when set of domains
+     changes.
+   * Added ikisite maintaincerts to request/renew Lets Encrypt certs as needed,
+     and added it to the daily cron job.
+   * The files /etc/ikiwiki-hosting/config/$username/domain.{crt,key,chain}
+     are used, when they exist, in preference to the files
+     /etc/ikiwiki-hosting/config/$username/ssl.{key,crt}. This allows
+     a site with multiple domains to have different certificates
+     for them. The Lets Encrypt support uses this."""]]
\ No newline at end of file

update
diff --git a/doc/design/apacheconfig.mdwn b/doc/design/apacheconfig.mdwn
index 6e68397..85523fb 100644
--- a/doc/design/apacheconfig.mdwn
+++ b/doc/design/apacheconfig.mdwn
@@ -22,6 +22,10 @@ Example:
 		AuthUserFile <TMPL_VAR HOME>/apache/htpasswd
 		Require valid-user
 	</Directory>
+	<Directory <TMPL_VAR HOME>/public_html/.well-known>
+	        AuthType None
+		Require all granted
+	</Directory>
 
 Note the use of "+" to add to the default Options, rather than overriding it.
 
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index df73e53..b2d285d 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -308,3 +308,13 @@ slow down site creation etc.
   Or, could make apache-sitealias.tmpl use per-domain cert files. This
   avoids all this complexity. Only the Registration/IP rate limit might be
   a problem with doing this, but it's sufficiently high. (done)
+
+* Sites with a apache.conf.tmpl password protecting the site 
+  will not be able to use letencrypt, unless it's relaxed to let
+  .well-known be accessed w/o password. This can be fixed by
+  adding this to the end of their apache.conf.tmpl file:
+
+	<Directory <TMPL_VAR HOME>/public_html/.well-known>
+		AuthType None
+		Require all granted
+	</Directory>

per-domain ssl cert files
The files /etc/ikiwiki-hosting/config/$username/domain.{crt,key,chain} are
used, when they exist, in preference to the files
/etc/ikiwiki-hosting/config/$username/ssl.{key,crt}. This allows a site
with multiple domains to have different certificates for them.
Change letsencrypt integration to always use per-domain ssl cert files.
This avoids renewal failure modes where one of several domains in a cert
has fallen out of the dns. And it avoids letsencrypt setup failure for a
site if some of its urlaliases are not setup correctly in the dns.
This commit was sponsored by Boyd Stephen Smith Jr. on Patreon.
diff --git a/debian/changelog b/debian/changelog
index 6aedc69..bf14da9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,9 +6,13 @@ ikiwiki-hosting (0.20160812) UNRELEASED; urgency=medium
     for it using certbot.
   * ikisite domains: Update certificate using certbot when set of domains
     changes.
-  * Renewal and retrying failed certificate requests are not yet implemented.
   * Added ikisite maintaincerts to request/renew Lets Encrypt certs as needed,
     and added it to the daily cron job.
+  * The files /etc/ikiwiki-hosting/config/$username/domain.{crt,key,chain}
+    are used, when they exist, in preference to the files
+    /etc/ikiwiki-hosting/config/$username/ssl.{key,crt}. This allows
+    a site with multiple domains to have different certificates
+    for them. The Lets Encrypt support uses this.
 
  -- Joey Hess <id@joeyh.name>  Thu, 13 Oct 2016 16:55:25 -0400
 
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 8cd9a37..df73e53 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -225,23 +225,23 @@ an error if the included file doesn't exist. So, something like:
 Add a `use_letsencrypt` config setting in the ikiwiki-hosting plugin.
 (done)
 
-Define a flag file, /etc/ikiwiki-hosting/config/$username/letsencrypt-setup
-which exists when letsencrypt has provided a certificate for a site.
-(done)
+Make /etc/ikiwiki-hosting/config/$username/domain.{crt,key,chain} be
+used for a domain when available, instead of ssl.{crt,key,chain}.
+This allows urlaliases to each get their own letsencrypt cert. (done)
 
 Add `ikisite letsencrypt site`, which first sets `use_letsencrypt`
 and then runs certbot (or whatever, it can be made configurable if
 desired) to try to get a certificate for all of the site's domain(s).
-If certbot succeeds, it symlinks the cert into place, touches the flag
-file, and calls `ikisite enable site` to update the web server config
+If certbot succeeds, it symlinks the cert into place,
+and calls `ikisite enable site` to update the web server config
 to use the cert. (done)
 
 Add `ikisite letsnotencrypt site` which undoes that. (done)
 
 Then add a daily cron job that looks for sites that have `use_letsencrypt`
-set, but don't have the flag file. For each such site, it runs
-`ikisite letsencrypt` to try again to get the cert. 
-(done in `ikisite maintaincerts`)
+set, but don't have letsencrypt certs. (Check that the cert files are
+symlinks to tell). For each such site, it runs `ikisite letsencrypt`
+to try again to get the cert. (done in `ikisite maintaincerts`)
 
 Another cron job can run `certbot renew` to handle all renewals.
 Seems this doesn't need to rejigger the certificate symlinks or the
@@ -307,4 +307,4 @@ slow down site creation etc.
 
   Or, could make apache-sitealias.tmpl use per-domain cert files. This
   avoids all this complexity. Only the Registration/IP rate limit might be
-  a problem with doing this, but it's sufficiently high.
+  a problem with doing this, but it's sufficiently high. (done)
diff --git a/ikisite b/ikisite
index 44701fd..6ccb061 100755
--- a/ikisite
+++ b/ikisite
@@ -973,24 +973,29 @@ sub rootconfig {
 	return $config{ikisite_rootconfigdir}."/".username($hostname);
 }
 
-sub ssl_cert_file {
+sub ssl_file {
+	my $ext=shift;
 	my $hostname=shift;
-	return rootconfig($hostname)."/ssl.crt";
-}
+	my $domain=shift;
+	my $no_fallback=shift;
 
-sub ssl_key_file {
-	my $hostname=shift;
-	return rootconfig($hostname)."/ssl.key";
+	my $perdomain=rootconfig($hostname)."/".$domain.".".$ext;
+	if ($no_fallback || -e $perdomain) {
+		return $perdomain;
+	}
+	else {
+		return rootconfig($hostname)."/ssl.".$ext;
+	}
 }
 
-sub ssl_chain_file {
-	my $hostname=shift;
-	return rootconfig($hostname)."/ssl.chain";
-}
+sub ssl_cert_file { ssl_file("crt", @_) }
+sub ssl_key_file { ssl_file("key", @_) }
+sub ssl_chain_file { ssl_file("chain", @_) }
 
-sub letsencrypt_flag_file {
-	my $hostname=shift;
-	return rootconfig($hostname)."/letsencrypt-setup";
+sub is_letsencrpt_link {
+	my $file=shift;
+	my $link=readlink($file);
+	return (defined $link && $link=~m!/etc/letsencrypt/live!);
 }
 
 sub meta_wikiname {
@@ -1591,74 +1596,9 @@ sub enable {
 	$u=~s://$:/:;
 	my $url=URI->new($u);
 	
-	my $ssl_cert_file=ssl_cert_file($hostname);
-	my $ssl_key_file=ssl_key_file($hostname);
-	my $ssl_chain_file=ssl_chain_file($hostname);
-	# Check that any user provided key file is not password protected,
-	# as that makes apache startup hang. (Also checks that it's valid.)
-	if (-e $ssl_key_file) {
-		if (shell_exitcode("openssl", "rsa",
-				"-in" => $ssl_key_file,
-				"-out" => $ssl_key_file, 
-				"-passin" => "pass:dummy",
-				"-passout" => "pass:dummy") != 0) {
-			$ssl_key_file='';
-			$ssl_cert_file='';
-			$ssl_chain_file='';
-		}
-	}
-	# Use wildcard cert if there is no site specific one, only
-	# if the site is not using its own domain name.
-	if (defined $config{wildcard_ssl_cert} && length $config{wildcard_ssl_cert} &&
-	    defined $config{wildcard_ssl_key} && length $config{wildcard_ssl_key} &&
-	    ! -e $ssl_cert_file && ! -e $ssl_key_file) {
-		my @domains = split(' ', $config{domains});
-		my $wildcard_ok=1;
-		foreach my $h (@hostnames) {
-			my $w_ok=0;
-			foreach my $d (@domains) {
-				if ($h =~ /^.+\.\Q$d\E$/i || $h eq $d) {
-					$w_ok=1;
-				}
-			}
-			$wildcard_ok = $wildcard_ok && $w_ok;
-		}
-		if ($wildcard_ok) {
-			$ssl_cert_file=$config{wildcard_ssl_cert};
-			$ssl_key_file=$config{wildcard_ssl_key};
-			if (defined $config{wildcard_ssl_chain} && length $config{wildcard_ssl_chain}) {
-				$ssl_chain_file=$config{wildcard_ssl_chain};
-			}
-			else {
-				$ssl_chain_file='';
-			}
-		}
-	}
-	my $ssl_enabled=-e $ssl_key_file && -e $ssl_cert_file;
-	my @ssl_template_vars=(
-		ssl_cert_file => $ssl_cert_file,
-		ssl_key_file => $ssl_key_file,
-		ssl_enabled => $ssl_enabled,
-	);
-	if (-e $ssl_chain_file) {
-		push @ssl_template_vars, (
-			ssl_chain_file => $ssl_chain_file,
-			ssl_chain => 1,
-		);
-	}
-
-	# This is the url that alias urls redirect to.
-	my $redirurl=$url;
-	my $httpsredirurl=$url->clone;
-	if ($ssl_enabled) {
-		$httpsredirurl->scheme("https");
-		if (getsetup($hostname, 'redirect_to_https')) {
-			$redirurl->scheme("https");
-			push @ssl_template_vars, (redirect_to_https => 1);
-		}
-	}
-
-	# generate apache config file
+	# write and enable apache config file
+	my $apache_site="ikisite-".$url->host;
+	my $apache_conf_file="/etc/apache2/sites-available/$apache_site.conf";
 	my @apache_template_vars=(
 		suexec => (cgidir($hostname) =~ m!^/var/www!),
 		user => $user,
@@ -1668,16 +1608,8 @@ sub enable {
 		cgidir => cgidir($hostname),
 		logdir => logdir($hostname),
 		source_hostname => "source.$hostname",
-		# Value escaped to prevent leakage
-		# into RewriteEngine regexp.
-		url_escaped => quotemeta($redirurl),
-		https_url_escaped => quotemeta($httpsredirurl),
-		@ssl_template_vars
+		domain_template_vars($hostname, $url->host, $url)
 	);
-
-	# write and enable apache config file
-	my $apache_site="ikisite-".$url->host;

(Diff truncated)
update
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index db63d3b..8cd9a37 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -305,6 +305,6 @@ slow down site creation etc.
   letsencrypt failed, and why. (Worth doing in any case, but I'm not sure
   where to put it in the UI.)
 
-  Or, could make apache-sitealias.tmpl use per-domain cert files. Then
-  enabling letsencrypt for a site with lots of urlaliases would burn
-  through the rate limits faster, but all this complexity would be avoided.
+  Or, could make apache-sitealias.tmpl use per-domain cert files. This
+  avoids all this complexity. Only the Registration/IP rate limit might be
+  a problem with doing this, but it's sufficiently high.

issue also affects renewals
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index b5a38cf..db63d3b 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -279,7 +279,6 @@ slow down site creation etc.
   it cannot verify it.
 
   This affects both `ikisite letsencrypt` and `ikisite domains`.
-  Unknown if it affects letsencrypt cert renewal.
 
   `ikisite domains` does not currently ensure that all urlaliases are set
   in the dns. This check could be added, it might cause some problem
@@ -290,7 +289,11 @@ slow down site creation etc.
   `templates/apache-sitealias.tmpl` includes a https configuration.
   That lets redirection from the https urlalias to the main url work.
 
-  This could be fixed by re-running certbot without the urlaliases if it
+  But also, if a cert is issued for domains A and B, and B later falls out
+  of the DNS, renewal of the cert will fail. So this can lead to renewal
+  failures later down the line.
+
+  Partial fix would be re-running certbot without the urlaliases if it
   fails with them. Better to have the main url encrypted even if
   redirection to it cannot be. But, that would leave the
   apache-sitealias.tmpl generating a config that uses the wrong cert for
@@ -299,4 +302,9 @@ slow down site creation etc.
   this case.
 
   Alternatively, could improve the UI so the site admin can see when
-  letsencrypt failed, and why. --[[Joey]]
+  letsencrypt failed, and why. (Worth doing in any case, but I'm not sure
+  where to put it in the UI.)
+
+  Or, could make apache-sitealias.tmpl use per-domain cert files. Then
+  enabling letsencrypt for a site with lots of urlaliases would burn
+  through the rate limits faster, but all this complexity would be avoided.

todo
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index fefd7fe..b5a38cf 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -284,3 +284,19 @@ slow down site creation etc.
   `ikisite domains` does not currently ensure that all urlaliases are set
   in the dns. This check could be added, it might cause some problem
   though.
+
+  Note that this is only a problem because the urlaliases are passed
+  to certbot as --host. That is needed because
+  `templates/apache-sitealias.tmpl` includes a https configuration.
+  That lets redirection from the https urlalias to the main url work.
+
+  This could be fixed by re-running certbot without the urlaliases if it
+  fails with them. Better to have the main url encrypted even if
+  redirection to it cannot be. But, that would leave the
+  apache-sitealias.tmpl generating a config that uses the wrong cert for
+  https, which is bad if some of the urlaliases are accessible in the dns.
+  So, this fix needs a way to prevent that template from using https in
+  this case.
+
+  Alternatively, could improve the UI so the site admin can see when
+  letsencrypt failed, and why. --[[Joey]]

problem
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 6c60ab3..fefd7fe 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -270,3 +270,17 @@ slow down site creation etc.
 > Note: there is already a cron job that runs certbot renew in the Debian package,
 > watch out for dupes... Otherwise: design sounds okay, although I'm not sure 
 > why the flag file is necessary. --[[anarcat]]
+
+## issues
+
+* If a site's urlalias includes some domain that is not in the DNS,
+  or no longer points to the host, this is normally not a problem.
+  But, it will prevent certbot getting a cert for that site, because
+  it cannot verify it.
+
+  This affects both `ikisite letsencrypt` and `ikisite domains`.
+  Unknown if it affects letsencrypt cert renewal.
+
+  `ikisite domains` does not currently ensure that all urlaliases are set
+  in the dns. This check could be added, it might cause some problem
+  though.

decruft
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index f1835a8..6c60ab3 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -266,9 +266,6 @@ restoring from backup, etc) should run `ikisite letsencrypt` at the end
 when the site has `use_letsencrypt` configured. It can take a minute or so
 for letsencrypt to run, so best to do that in the background so as to not
 slow down site creation etc.
-by setting letsencrypt=true in ikiwiki-hosting.conf. Then every
-ikisite command that creates a site (including branching, restoring from
-backup, etc) should run `ikisite letsencrypt` at the end.
 
 > Note: there is already a cron job that runs certbot renew in the Debian package,
 > watch out for dupes... Otherwise: design sounds okay, although I'm not sure 

Merge branch 'master' of ssh://ikiwiki-hosting.branchable.com
Added ikisite maintaincerts to request/renew Lets Encrypt certs as needed, and added it to the daily cron job.
This commit was sponsored by Remy van Elst on Patreon.
diff --git a/debian/changelog b/debian/changelog
index 1c59f36..6aedc69 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -7,6 +7,8 @@ ikiwiki-hosting (0.20160812) UNRELEASED; urgency=medium
   * ikisite domains: Update certificate using certbot when set of domains
     changes.
   * Renewal and retrying failed certificate requests are not yet implemented.
+  * Added ikisite maintaincerts to request/renew Lets Encrypt certs as needed,
+    and added it to the daily cron job.
 
  -- Joey Hess <id@joeyh.name>  Thu, 13 Oct 2016 16:55:25 -0400
 
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 8f2b149..6751cc3 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -236,20 +236,17 @@ If certbot succeeds, it symlinks the cert into place, touches the flag
 file, and calls `ikisite enable site` to update the web server config
 to use the cert. (done)
 
-> Testing this on a system with the jessie certbot backport, certbot
-> fails with "The server experienced an internal error :: Error creating
-> new cert". The log says that the letsencrypt server returned an error
-> 500. --[[Joey]]
-
 Add `ikisite letsnotencrypt site` which undoes that. (done)
 
 Then add a daily cron job that looks for sites that have `use_letsencrypt`
 set, but don't have the flag file. For each such site, it runs
-`ikisite letsencrypt` to try again to get the cert.
+`ikisite letsencrypt` to try again to get the cert. 
+(done in `ikisite maintaincerts`)
 
 Another cron job can run `certbot renew` to handle all renewals.
 Seems this doesn't need to rejigger the certificate symlinks or the
 apache config for renewed sites, so it should be nice and simple.
+(done in `ikisite maintaincerts`)
 
 `ikisite domains` will need to check `use_letsencrypt`. If it's set, and a
 new domain is being added to a site, or a domain removed, it needs to
diff --git a/ikisite b/ikisite
index aa7a38f..fb27785 100755
--- a/ikisite
+++ b/ikisite
@@ -699,6 +699,7 @@ sub list {
 				site_wikiname => getsetup($hostname, "wikiname"),
 				site_created => getsetup($hostname, "created"),
 				site_parent => getsetup($hostname, "parent"),
+				use_letsencrypt => getsetup($hostname, "use_letsencrypt"),
 				isunfinished => $unfinished,
 			};
 		}
@@ -1889,6 +1890,33 @@ sub letsnotencrypt {
 	enable($hostname);
 }
 
+sub meta_maintaincerts {
+	required => [],
+	options => [qw{}],
+	description => "request and renew Lets Encrypt certificates as needed",
+	section => "utility",
+}
+sub maintaincerts {
+	assert_root();
+	assert_wrapper_denied();
+
+	my $inuse=0;
+	foreach my $site (list(extended => 1)) {
+		next if $site->{isunfinished};
+		next unless $site->{use_letsencrypt};
+		$inuse=1;
+		letsencrypt($site->{hostname})
+			unless -e letsencrypt_flag_file($site->{hostname});
+	}
+
+	if ($inuse) {
+		eval { shell("certbot", "renew", "--non-interactive") };
+		eval { shell("apache2ctl", "graceful") };
+	}
+
+	return 1;
+}
+
 sub meta_enabledns {
 	required => [qw{hostname}],
 	options => [qw{}],
diff --git a/ikiwiki-hosting-web-daily b/ikiwiki-hosting-web-daily
index eb6befb..a10f4a0 100755
--- a/ikiwiki-hosting-web-daily
+++ b/ikiwiki-hosting-web-daily
@@ -21,7 +21,10 @@ done
 
 # Reload apache so it will start logging to the new site log files.
 /etc/init.d/apache2 reload
-		
+
+# Request and renew any Lets Encrypt certs as needed.
+ikisite maintaincerts
+
 if [ "$failed" ]; then
 	exit 1
 else

update
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 45cf821..8f2b149 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -236,6 +236,11 @@ If certbot succeeds, it symlinks the cert into place, touches the flag
 file, and calls `ikisite enable site` to update the web server config
 to use the cert. (done)
 
+> Testing this on a system with the jessie certbot backport, certbot
+> fails with "The server experienced an internal error :: Error creating
+> new cert". The log says that the letsencrypt server returned an error
+> 500. --[[Joey]]
+
 Add `ikisite letsnotencrypt site` which undoes that. (done)
 
 Then add a daily cron job that looks for sites that have `use_letsencrypt`
@@ -261,4 +266,6 @@ Once this is tested and working well, it can be made the default,
 by setting `use_letsencrypt` in the autosetup/ files. For that to work,
 every ikisite command that creates a site (including branching,
 restoring from backup, etc) should run `ikisite letsencrypt` at the end
-when the site has `use_letsencrypt` configured.
+when the site has `use_letsencrypt` configured. It can take a minute or so
+for letsencrypt to run, so best to do that in the background so as to not
+slow down site creation etc.

update on status
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 615590a..45cf821 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -223,16 +223,20 @@ an error if the included file doesn't exist. So, something like:
 ## Worked design
 
 Add a `use_letsencrypt` config setting in the ikiwiki-hosting plugin.
+(done)
 
 Define a flag file, /etc/ikiwiki-hosting/config/$username/letsencrypt-setup
 which exists when letsencrypt has provided a certificate for a site.
+(done)
 
 Add `ikisite letsencrypt site`, which first sets `use_letsencrypt`
 and then runs certbot (or whatever, it can be made configurable if
 desired) to try to get a certificate for all of the site's domain(s).
 If certbot succeeds, it symlinks the cert into place, touches the flag
 file, and calls `ikisite enable site` to update the web server config
-to use the cert.
+to use the cert. (done)
+
+Add `ikisite letsnotencrypt site` which undoes that. (done)
 
 Then add a daily cron job that looks for sites that have `use_letsencrypt`
 set, but don't have the flag file. For each such site, it runs
@@ -251,6 +255,7 @@ an alias. Certianly not in the case where the site's primary domain has
 changed. The safe option is certainly to remove the old letsencrypt
 certificate if it fails, and `ikisite enable` will then disable ssl support
 for that site, until the cron job later succeeds in getting a certificate.
+(done)
 
 Once this is tested and working well, it can be made the default,
 by setting `use_letsencrypt` in the autosetup/ files. For that to work,

simplify
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 6cc9390..615590a 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -253,6 +253,7 @@ certificate if it fails, and `ikisite enable` will then disable ssl support
 for that site, until the cron job later succeeds in getting a certificate.
 
 Once this is tested and working well, it can be made the default,
-by setting letsencrypt=true in ikiwiki-hosting.conf. Then every
-ikisite command that creates a site (including branching, restoring from
-backup, etc) should run `ikisite letsencrypt` at the end.
+by setting `use_letsencrypt` in the autosetup/ files. For that to work,
+every ikisite command that creates a site (including branching,
+restoring from backup, etc) should run `ikisite letsencrypt` at the end
+when the site has `use_letsencrypt` configured.

no need to unset redirect_to_https when disabling letsencrypt
That config is only used when there are certificates available.
Also, forgot to enable the site after disabling letsencrypt, in order to
update the apache config..
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 419cdef..6cc9390 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -251,7 +251,6 @@ an alias. Certianly not in the case where the site's primary domain has
 changed. The safe option is certainly to remove the old letsencrypt
 certificate if it fails, and `ikisite enable` will then disable ssl support
 for that site, until the cron job later succeeds in getting a certificate.
-(Also need to unset `redirect_to_https` in this case if it was set before.)
 
 Once this is tested and working well, it can be made the default,
 by setting letsencrypt=true in ikiwiki-hosting.conf. Then every
diff --git a/ikisite b/ikisite
index 5ba6e2b..aa7a38f 100755
--- a/ikisite
+++ b/ikisite
@@ -1878,7 +1878,6 @@ sub letsnotencrypt {
 		message => "letsencrypt disabled",
 		set => [
 			"use_letsencrypt=0",
-			"redirect_to_https=0",
 		],
 	) unless $options{temporary};
 
@@ -1887,8 +1886,7 @@ sub letsnotencrypt {
 	unlink(ssl_key_file($hostname));
 	unlink(ssl_chain_file($hostname));
 	unlink(letsencrypt_flag_file($hostname));
-
-	return 1;
+	enable($hostname);
 }
 
 sub meta_enabledns {

Initial support for Lets Encrypt.
* Initial support for Lets Encrypt.
* The use_letsencrypt setting can be set for a site by running
ikisite letsencrypt domain, and it will attempt to get the certificate
for it using certbot.
* ikisite domains: Update certificate using certbot when set of domains
changes.
* Renewal and retrying failed certificate requests are not yet implemented.
This commit was sponsored by Jeff Goeke-Smith on Patreon.
diff --git a/IkiWiki/Plugin/ikiwikihosting.pm b/IkiWiki/Plugin/ikiwikihosting.pm
index 626b7d2..9a51d88 100644
--- a/IkiWiki/Plugin/ikiwikihosting.pm
+++ b/IkiWiki/Plugin/ikiwikihosting.pm
@@ -76,6 +76,13 @@ sub getsetup () {
 			safe => 1,
 			rebuild => 0,
 		},
+		use_letsencrypt => {
+			type => "boolean",
+			example => 1,
+			description => "use Lets Encrypt to generate http certificate?",
+			safe => 1,
+			rebuild => 0,
+		},
 }
 
 sub sessioncgi ($$) {
diff --git a/debian/changelog b/debian/changelog
index 5c12748..1c59f36 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+ikiwiki-hosting (0.20160812) UNRELEASED; urgency=medium
+
+  * Initial support for Lets Encrypt.
+  * The use_letsencrypt setting can be set for a site by running
+    ikisite letsencrypt domain, and it will attempt to get the certificate
+    for it using certbot.
+  * ikisite domains: Update certificate using certbot when set of domains
+    changes.
+  * Renewal and retrying failed certificate requests are not yet implemented.
+
+ -- Joey Hess <id@joeyh.name>  Thu, 13 Oct 2016 16:55:25 -0400
+
 ikiwiki-hosting (0.20160811) unstable; urgency=medium
 
   * Explicitly remove current working directory from Perl's library
diff --git a/debian/control b/debian/control
index 9784216..fdaad04 100644
--- a/debian/control
+++ b/debian/control
@@ -94,6 +94,7 @@ Depends:
  polygen-data,
  python-docutils,
  uuid,
+ certbot,
  ${misc:Depends},
  ${perl:Depends},
  ${shlibs:Depends},
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 938a4af..419cdef 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -225,7 +225,7 @@ an error if the included file doesn't exist. So, something like:
 Add a `use_letsencrypt` config setting in the ikiwiki-hosting plugin.
 
 Define a flag file, /etc/ikiwiki-hosting/config/$username/letsencrypt-setup
-which exists when letsencrypt is being used for a site.
+which exists when letsencrypt has provided a certificate for a site.
 
 Add `ikisite letsencrypt site`, which first sets `use_letsencrypt`
 and then runs certbot (or whatever, it can be made configurable if
diff --git a/ikisite b/ikisite
index 66622f6..5ba6e2b 100755
--- a/ikisite
+++ b/ikisite
@@ -972,6 +972,26 @@ sub rootconfig {
 	return $config{ikisite_rootconfigdir}."/".username($hostname);
 }
 
+sub ssl_cert_file {
+	my $hostname=shift;
+	return rootconfig($hostname)."/ssl.crt";
+}
+
+sub ssl_key_file {
+	my $hostname=shift;
+	return rootconfig($hostname)."/ssl.key";
+}
+
+sub ssl_chain_file {
+	my $hostname=shift;
+	return rootconfig($hostname)."/ssl.chain";
+}
+
+sub letsencrypt_flag_file {
+	my $hostname=shift;
+	return rootconfig($hostname)."/letsencrypt-setup";
+}
+
 sub meta_wikiname {
 	required => [qw{hostname}],
 	options => [qw{}],
@@ -1208,10 +1228,13 @@ sub domains {
 	
 	# This subcommand can be run from a suid wrapper so inputs
 	# cannot be trusted; check and sanitize.
+	my @newdomains;
 	my @urlalias;
 	my @settings;
 	my $rebuild=0;
 	if (defined $options{external}) {
+		push @newdomains, $options{external};
+
 		if (isinternaldomain($options{external})) {
 			error "$options{external} is a reserved hostname";
 		}
@@ -1256,6 +1279,7 @@ sub domains {
 			"url=http://$hostname",
 			"cgiurl=http://$hostname/ikiwiki.cgi",
 		];
+		push @newdomains, $hostname;
 	}
 	my %seen;
 	foreach my $alias (@{$options{alias}}) {
@@ -1288,6 +1312,12 @@ sub domains {
 		"urlalias=".Dump(\@urlalias),
 	];
 
+	push @newdomains, @urlalias;
+	my @olddomains;
+	foreach my $url (urllist(username($hostname))) {
+		push @olddomains, $url->host;
+	}
+
 	disable($hostname, temporary => 1);
 	changesetup($hostname,
 		rebuild => 0, # not yet; slow
@@ -1297,6 +1327,21 @@ sub domains {
 	);
 	enable($hostname);
 
+	# When there was a change to the set of domains used for a site,
+	# need to either get a new cert from letsencrypt, or temporarily
+	# disable using the old cert. This has to come after the site is
+	# enabled using the new domains, so that letsencrypt can get certs
+	# for them.
+	if (getsetup($hostname, "use_letsencrypt")) {
+		eval q{use Data::Compare};
+		error $@ if $@;
+		my $domainschanged = ! Compare([sort @olddomains], [sort @newdomains]);
+		if ($domainschanged &&
+			! letsencrypt($hostname)) {
+			letsnotencrypt($hostname, temporary => 1);
+		}
+	}
+
 	if ($rebuild) {
 		# A full site rebuild can take a long time for
 		# large sites, so is postponed until after the site's
@@ -1545,9 +1590,9 @@ sub enable {
 	$u=~s://$:/:;
 	my $url=URI->new($u);
 	
-	my $ssl_cert_file=rootconfig($hostname)."/ssl.crt";
-	my $ssl_key_file=rootconfig($hostname)."/ssl.key";
-	my $ssl_chain_file=rootconfig($hostname)."/ssl.chain";
+	my $ssl_cert_file=ssl_cert_file($hostname);
+	my $ssl_key_file=ssl_key_file($hostname);
+	my $ssl_chain_file=ssl_chain_file($hostname);
 	# Check that any user provided key file is not password protected,
 	# as that makes apache startup hang. (Also checks that it's valid.)
 	if (-e $ssl_key_file) {
@@ -1761,6 +1806,91 @@ sub disable {
 	return 1;
 }
 
+sub meta_letsencrypt {
+	required => [qw{hostname}],
+	options => [qw{}],
+	description => "use Lets Encrypt to get https certificate",
+	section => "utility",
+}
+sub letsencrypt {
+	my $hostname=lc(shift);
+
+	assert_root();
+	my $lockfile=locksite($hostname);
+	assert_wrapper_denied();
+
+	changesetup($hostname,
+		rebuild => 0,
+		commit => 1,
+		message => "letsencrypt enabled",
+		set => [
+			"use_letsencrypt=1",
+		],
+	);
+
+	my @domainparams;
+	foreach my $url (urllist(username($hostname))) {
+		push @domainparams, ("--domain=".$url->host);
+	}
+
+	if (shell_exitcode("certbot", "certonly",
+		"--text", "--noninteractive", "--keep-until-expiring",
+		"--agree-tos", "--email=$config{adminemail}",
+		"--webroot", "--webroot-path", destdir($hostname),
+		@domainparams)) {

(Diff truncated)
watch out for dupe cronjobs
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 938a4af..82aa129 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -257,3 +257,7 @@ Once this is tested and working well, it can be made the default,
 by setting letsencrypt=true in ikiwiki-hosting.conf. Then every
 ikisite command that creates a site (including branching, restoring from
 backup, etc) should run `ikisite letsencrypt` at the end.
+
+> Note: there is already a cron job that runs certbot renew in the Debian package,
+> watch out for dupes... Otherwise: design sounds okay, although I'm not sure 
+> why the flag file is necessary. --[[anarcat]]

worked design
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 86dcd29..938a4af 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -137,14 +137,19 @@ Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets
 > So, this seems a pretty big problem; ikiwiki-hosting sites often use
 > subdomains, and if so, quite likely use more than 5. It could keep a site
 > site http-only until it got a cert. But with 100 sites, that would be nearly
-> half a year of delay! 
+> half a year of delay! (Update: With the new 20 certs/domain/week, that
+> drops to 5 weeks delay.)
+
 > And, what about renewal, wouldn't that be rate limited too?
 > (Update: No, it seems that renewals are not rate limited in the 20
 > certs/domain/week bucket.)
 > 
 > Seems like getting a cert for 100 subdomains under branchable.com (eg),
 > and then moving onto the next cert etc would be the best we could do. But
-> that's a lot more complicated.
+> that's a lot more complicated. In particular, renewal needs to use the
+> same set of 100 domains, and if one of the domains is deleted in the
+> meantime, renewal of those 100 probably won't work, and a new certificate
+> would need to be generated for the 99 remaining.
 > --[[Joey]]
 
 >> Ouch, yes, that is a significant problem for branchable!!! Maybe this should be brought up upstream... I wonder if this couldn't be a way to finance letsencrypt, to have larger providers pay a monthly fee for the service, and bypass those limits. --[[anarcat]]
@@ -210,3 +215,45 @@ an error if the included file doesn't exist. So, something like:
 	IncludeOptional /etc/apache2/sites-available/$domain/*.conf
 
 >> The way I did this here was to generate the cert with the HTTP-only vhost, and only after the cert was generated create the HTTPS vhost... Can't you  have a modified HTTPS vhost generated only *after* the cert is generated? --[[anarcat]]
+
+>>> Yes, I think your approach at the top works; `ikisite enable $domain`
+>>> notices the certs and regenerates an apache config to use them.
+>>> --[[Joey]]
+
+## Worked design
+
+Add a `use_letsencrypt` config setting in the ikiwiki-hosting plugin.
+
+Define a flag file, /etc/ikiwiki-hosting/config/$username/letsencrypt-setup
+which exists when letsencrypt is being used for a site.
+
+Add `ikisite letsencrypt site`, which first sets `use_letsencrypt`
+and then runs certbot (or whatever, it can be made configurable if
+desired) to try to get a certificate for all of the site's domain(s).
+If certbot succeeds, it symlinks the cert into place, touches the flag
+file, and calls `ikisite enable site` to update the web server config
+to use the cert.
+
+Then add a daily cron job that looks for sites that have `use_letsencrypt`
+set, but don't have the flag file. For each such site, it runs
+`ikisite letsencrypt` to try again to get the cert.
+
+Another cron job can run `certbot renew` to handle all renewals.
+Seems this doesn't need to rejigger the certificate symlinks or the
+apache config for renewed sites, so it should be nice and simple.
+
+`ikisite domains` will need to check `use_letsencrypt`. If it's set, and a
+new domain is being added to a site, or a domain removed, it needs to
+delete the flag file and run `ikisite letsencrypt` to (try to) get a new
+certificate. What if that fails? It might be possible to keep using the old
+letsencrypt certificate in some cases, eg when adding
+an alias. Certianly not in the case where the site's primary domain has
+changed. The safe option is certainly to remove the old letsencrypt
+certificate if it fails, and `ikisite enable` will then disable ssl support
+for that site, until the cron job later succeeds in getting a certificate.
+(Also need to unset `redirect_to_https` in this case if it was set before.)
+
+Once this is tested and working well, it can be made the default,
+by setting letsencrypt=true in ikiwiki-hosting.conf. Then every
+ikisite command that creates a site (including branching, restoring from
+backup, etc) should run `ikisite letsencrypt` at the end.

Merge branch 'master' of ssh://ikiwiki-hosting.branchable.com
update
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 36d6837..e1c6fdc 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -127,6 +127,8 @@ Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets
 > site http-only until it got a cert. But with 100 sites, that would be nearly
 > half a year of delay! 
 > And, what about renewal, wouldn't that be rate limited too?
+> (Update: No, it seems that renewals are not rate limited in the 20
+> certs/domain/week bucket.)
 > 
 > Seems like getting a cert for 100 subdomains under branchable.com (eg),
 > and then moving onto the next cert etc would be the best we could do. But

diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 59cc7eb..ee90180 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -61,7 +61,7 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
 
  * [dehydrated][], bash-only client that should work all Debian
    releases back to Wheezy (formerly known as letsencrypt.sh, in [Debian jessie, stretch and sid](https://tracker.debian.org/pkg/letsencrypt.sh))
- * [simp_le][], much simpler implementation in Python (not in Debian)
+ * [simp_le][], much simpler implementation in Python ([not in Debian](https://github.com/kuba/simp_le/issues/69))
  * [acme][], root-less, more minimal implementation than the official
    client, in Go ([in Debian stretch and sid](https://tracker.debian.org/pkg/acmetool))
  * [acme-tiny][] is a very small client (~200 lines of python code)

client updates
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 5c5bfba..59cc7eb 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -59,11 +59,11 @@ Potential clients
 
 Finally, note that there is now a fairly [large set of Let's Encrypt clients][], here's a short list (those have not been reviewed or tested for compatiblity with ikiwiki-hosting):
 
- * [letsencrypt.sh][], bash-only client that should work all Debian
-   releases back to Wheezy
+ * [dehydrated][], bash-only client that should work all Debian
+   releases back to Wheezy (formerly known as letsencrypt.sh, in [Debian jessie, stretch and sid](https://tracker.debian.org/pkg/letsencrypt.sh))
  * [simp_le][], much simpler implementation in Python (not in Debian)
  * [acme][], root-less, more minimal implementation than the official
-   client, in Go ([ITP for acmetool][])
+   client, in Go ([in Debian stretch and sid](https://tracker.debian.org/pkg/acmetool))
  * [acme-tiny][] is a very small client (~200 lines of python code)
    that aims to be easily audited and to do only one thing well. for
    example, you need to generate your RSA key yourself, which may
@@ -74,7 +74,7 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
  [plugin]: https://github.com/letsencrypt/letsencrypt/wiki/Plugins
  [large set of Let's Encrypt clients]: https://github.com/letsencrypt/letsencrypt/wiki/Links
  [simp_le]: https://github.com/kuba/simp_le
- [letsencrypt.sh]: https://github.com/lukas2511/letsencrypt.sh
+ [dehydrated]: https://dehydrated.de/
  [acme]: https://github.com/hlandau/acme
  [letsacme]: https://github.com/neurobin/letsacme
  [acme-tiny]: https://github.com/diafygi/acme-tiny/

update on renewals: mostly done, just need to hook this in ikisite now
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 36d6837..5c5bfba 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -81,6 +81,8 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
  [ITP for acmetool]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=817091
  [in Debian stretch and sid]: https://tracker.debian.org/pkg/acme-tiny
 
+Note that I have also considered simply using the `--apache` plugin to just have LE manage all those certs itself. This could conflict with ikiwiki-hosting, but since it runs fairly frequently, it could just win in the end. It's not a great solution for sites managed by the control panel, but for my use case, it could just work. Unforunately, it [parses configs in sites-available instead of just sites-enabled](https://github.com/certbot/certbot/issues/3545) which breaks it for me. --[[anarcat]]
+
 Renewals
 --------
 
@@ -104,10 +106,20 @@ Also, renewals need to be processed in some way. It seems that it's possible to
 
 >>>> So the software name changed: it's certbot now. And yes, the renew command seems to work better. There is a `--post-hook` that can restart apache and do various things with certs, but unfortunately prior to 0.7, it runs all the time. Normally, the `--post-hook` is one of those variables that would be saved on renewal, but I haven't tested this because I don't want to have that hook run twice a day. So I'm waiting for this to hit backports before automating this completely, especially since I do not want to diverge from the package's `/etc/cron.d/certbot` cronjob. My test renewal line now looks like:
 >>>>
->>>>     certbot --dry-run renew --post-hook 'service apache2 reload; etckeeper commit "certbot renewed domains: $RENEWED_DOMAINS"'
+>>>>     certbot --dry-run renew --renew-hook 'service apache2 reload; etckeeper commit "certbot renewed domains: $RENEWED_DOMAINS"'
 >>>> 
 >>>> I'll test this again in a few weeks, hopefully when the [new package hits backports](http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=826147). --[[anarcat]]
 
+>>>> The software has caught up. To avoid customizing the config file, I had to put the renew-hook in the `/etc/letsencrypt/cli.ini` config file, as such:
+>>>> 
+>>>>     renew-hook = service apache2 reload & etckeeper commit "certbot renewed domains: $RENEWED_DOMAINS"
+>>>>
+>>>> Notice the `&` instead of `;` because the latter breaks the LE config file parser. With that, the configured domains are renewed automatically! To add new domains, I just need to repeat steps 3 to 5 above. Note that extra webroots can be specified with:
+>>>>
+>>>>     certbot certonly -w /home/foo -d foo.example.com -w /home/bar -d bar.example.com
+>>>>
+>>>> I.e. the last webroot path is attached to the next domain specified. Next step is to code this in Perl, I guess? --[[anarcat]]
+
 Rate limits
 -----------
 

Announce 0.20160811
diff --git a/doc/news/version_0.20160811.mdwn b/doc/news/version_0.20160811.mdwn
new file mode 100644
index 0000000..4614d05
--- /dev/null
+++ b/doc/news/version_0.20160811.mdwn
@@ -0,0 +1,8 @@
+ikiwiki-hosting 0.20160811 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Explicitly remove current working directory from Perl's library
+     search path, mitigating CVE-2016-1238 (see [[!debbug 588017]])
+   * Debian packaging:
+     - Add a simple autopkgtest for creating and deleting a site
+     - Standards-Version: 3.9.8 (no changes required)
+     - debian/rules: enable compiler hardening"""]]

reload should be enough
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index c3337fc..36d6837 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -98,13 +98,13 @@ Also, renewals need to be processed in some way. It seems that it's possible to
 
 >>> Actually, the `-c /etc/letsenctypt/renewal/$domain.conf` doesn't work at all. The 0.4 client features a new `renew` command that does the right thing (including renewing only if necessary). I tested it here and it seems to work fairly well. My complete update run looks more something like this now: --[[anarcat]]
 
->>>    letsencrypt renew --non-interactive
->>>    git -C /etc add -A letsencrypt
->>>    git commit -m"renew all certs"
+>>>     letsencrypt renew --non-interactive
+>>>     git -C /etc add -A letsencrypt
+>>>     git commit -m"renew all certs"
 
 >>>> So the software name changed: it's certbot now. And yes, the renew command seems to work better. There is a `--post-hook` that can restart apache and do various things with certs, but unfortunately prior to 0.7, it runs all the time. Normally, the `--post-hook` is one of those variables that would be saved on renewal, but I haven't tested this because I don't want to have that hook run twice a day. So I'm waiting for this to hit backports before automating this completely, especially since I do not want to diverge from the package's `/etc/cron.d/certbot` cronjob. My test renewal line now looks like:
 >>>>
->>>>    certbot --dry-run renew --post-hook 'service apache2 restart; etckeeper commit "certbot renewed domains: $RENEWED_DOMAINS"'
+>>>>     certbot --dry-run renew --post-hook 'service apache2 reload; etckeeper commit "certbot renewed domains: $RENEWED_DOMAINS"'
 >>>> 
 >>>> I'll test this again in a few weeks, hopefully when the [new package hits backports](http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=826147). --[[anarcat]]
 

some certbot changes
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index d13d7f4..c3337fc 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -5,7 +5,7 @@ it would be great if, as part of the SSL integration, ikiwiki-hosting would call
 First implementation
 --------------------
 
-so far I have done this by hand, using the main client:
+so far I have done this by hand, using the main client (previously called letsencrypt, now called certbot, those instructions may need to be updated):
 
 1. define some handy variables:
 
@@ -18,19 +18,19 @@ so far I have done this by hand, using the main client:
 
    * if you are on Debian sid, stretch or jessie (with backports):
 
-            apt install letsencrypt
+            apt install certbot
 
    * otherwise, run the magic commands:
 
-            git clone https://github.com/letsencrypt/letsencrypt
-            cd letsencrypt
-            ./letsencrypt-auto --server https://acme-v01.api.letsencrypt.org/directory --help
+            git clone https://github.com/certbot/certbot
+            cd certbot
+            ./cerbot-auto --help
 
 3. request a certificate:
 
         sudo -s
         [ -d .git ] && source venv/bin/activate # only use virtualenv if checking out from git
-        letsencrypt certonly --webroot \
+        certbot certonly --webroot \
           --agree-tos \
           --webroot-path="$webroot" \
           --domains $domain --email $email
@@ -52,7 +52,7 @@ so far I have done this by hand, using the main client:
         service apache2 reload # or restart?
 
 Ikiwiki hosting would need to perform steps 3 to 5, and probably have
-a `Recommends` on letsencrypt. -- [[anarcat]]
+a `Recommends` on certbot. -- [[anarcat]]
 
 Potential clients
 -----------------
@@ -98,9 +98,15 @@ Also, renewals need to be processed in some way. It seems that it's possible to
 
 >>> Actually, the `-c /etc/letsenctypt/renewal/$domain.conf` doesn't work at all. The 0.4 client features a new `renew` command that does the right thing (including renewing only if necessary). I tested it here and it seems to work fairly well. My complete update run looks more something like this now: --[[anarcat]]
 
-    letsencrypt renew --non-interactive
-    git -C /etc add -A letsencrypt
-    git commit -m"renew all certs"
+>>>    letsencrypt renew --non-interactive
+>>>    git -C /etc add -A letsencrypt
+>>>    git commit -m"renew all certs"
+
+>>>> So the software name changed: it's certbot now. And yes, the renew command seems to work better. There is a `--post-hook` that can restart apache and do various things with certs, but unfortunately prior to 0.7, it runs all the time. Normally, the `--post-hook` is one of those variables that would be saved on renewal, but I haven't tested this because I don't want to have that hook run twice a day. So I'm waiting for this to hit backports before automating this completely, especially since I do not want to diverge from the package's `/etc/cron.d/certbot` cronjob. My test renewal line now looks like:
+>>>>
+>>>>    certbot --dry-run renew --post-hook 'service apache2 restart; etckeeper commit "certbot renewed domains: $RENEWED_DOMAINS"'
+>>>> 
+>>>> I'll test this again in a few weeks, hopefully when the [new package hits backports](http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=826147). --[[anarcat]]
 
 Rate limits
 -----------

one limit changed
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 8f804dd..d13d7f4 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -108,7 +108,7 @@ Rate limits
 Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets-encrypt/6769), they don't seem to be a problem unless you run a really huge site (500 registrations per 3 hours per IP!). The limits are:
 
  * 100 Names/Certificate (how many domain names you can include in a single certificate)
- * 5 Certificates per Domain per week
+ * 20 Certificates per Domain per week
  * 500 Registrations/IP address per 3 hours
  * 300 Pending Authorizations/Account per week
 
@@ -130,6 +130,9 @@ Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets
 >> Ouch, yes, that is a significant problem for branchable!!! Maybe this should be brought up upstream... I wonder if this couldn't be a way to finance letsencrypt, to have larger providers pay a monthly fee for the service, and bypass those limits. --[[anarcat]]
 
 >>> [WP.com switched to LE](https://en.blog.wordpress.com/2016/04/08/https-everywhere-encryption-for-all-wordpress-com-sites/), so there's probably a way around those. --[[anarcat]]
+
+>>> I [asked around](https://news.ycombinator.com/item?id=11460480) and the limits were bumped to 20 certs/domain/week recently. Also, they can tweak the limits upon request. --[[anarcat]
+
 Discussion
 ----------
 

wp.com switched!
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 8640b01..8f804dd 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -129,6 +129,7 @@ Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets
 
 >> Ouch, yes, that is a significant problem for branchable!!! Maybe this should be brought up upstream... I wonder if this couldn't be a way to finance letsencrypt, to have larger providers pay a monthly fee for the service, and bypass those limits. --[[anarcat]]
 
+>>> [WP.com switched to LE](https://en.blog.wordpress.com/2016/04/08/https-everywhere-encryption-for-all-wordpress-com-sites/), so there's probably a way around those. --[[anarcat]]
 Discussion
 ----------
 

renewal fixes
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index f4fc3b8..8640b01 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -29,7 +29,7 @@ so far I have done this by hand, using the main client:
 3. request a certificate:
 
         sudo -s
-        source venv/bin/activate
+        [ -d .git ] && source venv/bin/activate # only use virtualenv if checking out from git
         letsencrypt certonly --webroot \
           --agree-tos \
           --webroot-path="$webroot" \
@@ -96,6 +96,12 @@ Also, renewals need to be processed in some way. It seems that it's possible to
 
 >> True, makes a lot more sense! --[[anarcat]]
 
+>>> Actually, the `-c /etc/letsenctypt/renewal/$domain.conf` doesn't work at all. The 0.4 client features a new `renew` command that does the right thing (including renewing only if necessary). I tested it here and it seems to work fairly well. My complete update run looks more something like this now: --[[anarcat]]
+
+    letsencrypt renew --non-interactive
+    git -C /etc add -A letsencrypt
+    git commit -m"renew all certs"
+
 Rate limits
 -----------
 

use wiki instead of discussion
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 2daf8c5..f4fc3b8 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -72,7 +72,7 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
 
  [letsencrypt.org gods]: https://letsencrypt.org
  [plugin]: https://github.com/letsencrypt/letsencrypt/wiki/Plugins
- [large set of Let's Encrypt clients]: https://community.letsencrypt.org/t/list-of-client-implementations/2103
+ [large set of Let's Encrypt clients]: https://github.com/letsencrypt/letsencrypt/wiki/Links
  [simp_le]: https://github.com/kuba/simp_le
  [letsencrypt.sh]: https://github.com/lukas2511/letsencrypt.sh
  [acme]: https://github.com/hlandau/acme

official client in debian backports, acme-tiny in stretch
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index a5899b2..2daf8c5 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -16,7 +16,7 @@ so far I have done this by hand, using the main client:
 
 2. install the letsencrypt client software:
 
-   * if you are on Debian sid, stretch (or when [letsencrypt enters backports][]):
+   * if you are on Debian sid, stretch or jessie (with backports):
 
             apt install letsencrypt
 
@@ -59,13 +59,18 @@ Potential clients
 
 Finally, note that there is now a fairly [large set of Let's Encrypt clients][], here's a short list (those have not been reviewed or tested for compatiblity with ikiwiki-hosting):
 
- * [letsencrypt.sh][], bash-only client that could work in Wheezy
- * [simp_le][], much simpler implementation in Python
- * [acme][], root-less, more minimal implementation than the official client, in Go
- * [acme-tiny][] is a very small client (~200 lines of python code) that aims to be easily audited and to do only one thing well. for example, you need to generate your RSA key yourself (which may actually be a good thing considering how ikiwiki-hosting works)
+ * [letsencrypt.sh][], bash-only client that should work all Debian
+   releases back to Wheezy
+ * [simp_le][], much simpler implementation in Python (not in Debian)
+ * [acme][], root-less, more minimal implementation than the official
+   client, in Go ([ITP for acmetool][])
+ * [acme-tiny][] is a very small client (~200 lines of python code)
+   that aims to be easily audited and to do only one thing well. for
+   example, you need to generate your RSA key yourself, which may
+   actually be a good thing considering how ikiwiki-hosting works
+   ([in Debian stretch and sid][])
 
  [letsencrypt.org gods]: https://letsencrypt.org
- [letsencrypt enters backports]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809018
  [plugin]: https://github.com/letsencrypt/letsencrypt/wiki/Plugins
  [large set of Let's Encrypt clients]: https://community.letsencrypt.org/t/list-of-client-implementations/2103
  [simp_le]: https://github.com/kuba/simp_le
@@ -73,6 +78,8 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
  [acme]: https://github.com/hlandau/acme
  [letsacme]: https://github.com/neurobin/letsacme
  [acme-tiny]: https://github.com/diafygi/acme-tiny/
+ [ITP for acmetool]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=817091
+ [in Debian stretch and sid]: https://tracker.debian.org/pkg/acme-tiny
 
 Renewals
 --------

toc
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index e60378b..a5899b2 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -1,5 +1,7 @@
 it would be great if, as part of the SSL integration, ikiwiki-hosting would call up on the [letsencrypt.org gods][] to install proper certs.
 
+[[!toc]]
+
 First implementation
 --------------------
 
@@ -62,6 +64,19 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
  * [acme][], root-less, more minimal implementation than the official client, in Go
  * [acme-tiny][] is a very small client (~200 lines of python code) that aims to be easily audited and to do only one thing well. for example, you need to generate your RSA key yourself (which may actually be a good thing considering how ikiwiki-hosting works)
 
+ [letsencrypt.org gods]: https://letsencrypt.org
+ [letsencrypt enters backports]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809018
+ [plugin]: https://github.com/letsencrypt/letsencrypt/wiki/Plugins
+ [large set of Let's Encrypt clients]: https://community.letsencrypt.org/t/list-of-client-implementations/2103
+ [simp_le]: https://github.com/kuba/simp_le
+ [letsencrypt.sh]: https://github.com/lukas2511/letsencrypt.sh
+ [acme]: https://github.com/hlandau/acme
+ [letsacme]: https://github.com/neurobin/letsacme
+ [acme-tiny]: https://github.com/diafygi/acme-tiny/
+
+Renewals
+--------
+
 Also, renewals need to be processed in some way. It seems that it's possible to just run:
 
     letsencrypt -c /etc/letsenctypt/renewal/$domain.conf --renew-by-default
@@ -74,16 +89,6 @@ Also, renewals need to be processed in some way. It seems that it's possible to
 
 >> True, makes a lot more sense! --[[anarcat]]
 
- [letsencrypt.org gods]: https://letsencrypt.org
- [letsencrypt enters backports]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809018
- [plugin]: https://github.com/letsencrypt/letsencrypt/wiki/Plugins
- [large set of Let's Encrypt clients]: https://community.letsencrypt.org/t/list-of-client-implementations/2103
- [simp_le]: https://github.com/kuba/simp_le
- [letsencrypt.sh]: https://github.com/lukas2511/letsencrypt.sh
- [acme]: https://github.com/hlandau/acme
- [letsacme]: https://github.com/neurobin/letsacme
- [acme-tiny]: https://github.com/diafygi/acme-tiny/
-
 Rate limits
 -----------
 

more answers
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index a08b0af..e60378b 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -166,3 +166,5 @@ Note that IncludeOptional has to be used with a wildcard to avoid it being
 an error if the included file doesn't exist. So, something like:
 
 	IncludeOptional /etc/apache2/sites-available/$domain/*.conf
+
+>> The way I did this here was to generate the cert with the HTTP-only vhost, and only after the cert was generated create the HTTPS vhost... Can't you  have a modified HTTPS vhost generated only *after* the cert is generated? --[[anarcat]]

re-merge rate-limit section, some answers and fixups
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index b36b63c..a08b0af 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -66,12 +66,14 @@ Also, renewals need to be processed in some way. It seems that it's possible to
 
     letsencrypt -c /etc/letsenctypt/renewal/$domain.conf --renew-by-default
 
-> --renew-by-default renews every time it's run; 
-> --keep-until-expiring instead waits until 30 days before expiry and 
+> `--renew-by-default` renews every time it's run; 
+> `--keep-until-expiring` instead waits until 30 days before expiry and 
 > renews then. I think that's the simpler approach, and the same
 > letsencrypt command line can then both obtain the original cert and renew
 > it. --[[Joey]]
 
+>> True, makes a lot more sense! --[[anarcat]]
+
  [letsencrypt.org gods]: https://letsencrypt.org
  [letsencrypt enters backports]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809018
  [plugin]: https://github.com/letsencrypt/letsencrypt/wiki/Plugins
@@ -92,6 +94,23 @@ Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets
  * 500 Registrations/IP address per 3 hours
  * 300 Pending Authorizations/Account per week
 
+> That seems to be 5 certificates per domain, not subdomain. 
+> Eg, I asked for tmp.kitenet.net 5 times and now it's not allowing
+> getting a cert for downloads.kitenet.net.
+> 
+> So, this seems a pretty big problem; ikiwiki-hosting sites often use
+> subdomains, and if so, quite likely use more than 5. It could keep a site
+> site http-only until it got a cert. But with 100 sites, that would be nearly
+> half a year of delay! 
+> And, what about renewal, wouldn't that be rate limited too?
+> 
+> Seems like getting a cert for 100 subdomains under branchable.com (eg),
+> and then moving onto the next cert etc would be the best we could do. But
+> that's a lot more complicated.
+> --[[Joey]]
+
+>> Ouch, yes, that is a significant problem for branchable!!! Maybe this should be brought up upstream... I wonder if this couldn't be a way to finance letsencrypt, to have larger providers pay a monthly fee for the service, and bypass those limits. --[[anarcat]]
+
 Discussion
 ----------
 
@@ -119,31 +138,9 @@ golang client ([lego][]), which has the interesting property of
 supporting DNS challenges. The puppet code itself uses the shell script
 previously mentioned. --[[anarcat]]
 
- [puppet implementation]:
- https://bzed.de/post/2016/02/bzed-letsencrypt_puppet_module/
+ [puppet implementation]: https://bzed.de/post/2016/02/bzed-letsencrypt_puppet_module/
  [lego]: https://github.com/xenolf/lego
 
-Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets-encrypt/6769), they don't seem to be a problem unless you run a really huge site (500 registrations per 3 hours per IP!). The limits are:
-
- * 100 Names/Certificate (how many domain names you can include in a single certificate)
- * 5 Certificates per Domain per week
- * 500 Registrations/IP address per 3 hours
- * 300 Pending Authorizations/Account per week
-
-> That seems to be 5 certificates per domain, not subdomain. 
-> Eg, I asked for tmp.kitenet.net 5 times and now it's not allowing
-> getting a cert for downloads.kitenet.net.
-> 
-> So, this seems a pretty big problem; ikiwiki-hosting sites often use
-> subdomains, and if so, quite likely use more than 5. It could keep a site
-> site http-only until it got a cert. But with 100 sites, that would be nearly
-> half a year of delay! 
-> And, what about renewal, wouldn't that be rate limited too?
-> 
-> Seems like getting a cert for 100 subdomains under branchable.com (eg),
-> and then moving onto the next cert etc would be the best we could do. But
-> that's a lot more complicated.
-> --[[Joey]]
 
 ---- 
 

expiry
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 469cd1c..b36b63c 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -130,6 +130,21 @@ Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets
  * 500 Registrations/IP address per 3 hours
  * 300 Pending Authorizations/Account per week
 
+> That seems to be 5 certificates per domain, not subdomain. 
+> Eg, I asked for tmp.kitenet.net 5 times and now it's not allowing
+> getting a cert for downloads.kitenet.net.
+> 
+> So, this seems a pretty big problem; ikiwiki-hosting sites often use
+> subdomains, and if so, quite likely use more than 5. It could keep a site
+> site http-only until it got a cert. But with 100 sites, that would be nearly
+> half a year of delay! 
+> And, what about renewal, wouldn't that be rate limited too?
+> 
+> Seems like getting a cert for 100 subdomains under branchable.com (eg),
+> and then moving onto the next cert etc would be the best we could do. But
+> that's a lot more complicated.
+> --[[Joey]]
+
 ---- 
 
 ## how to only enable ssl once a certificate is available

Merge branch 'master' of ssh://ikiwiki-hosting.branchable.com
update
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index b40439a..9b0bd02 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -26,7 +26,7 @@ so far I have done this by hand:
         sudo -s
         source venv/bin/activate
         letsencrypt certonly --webroot \
-          --agree-dev-preview --agree-tos \
+          --agree-tos \
           --webroot-path="$webroot" \
           --domains $domain --email $email
 
@@ -60,7 +60,13 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
 
 Also, renewals need to be processed in some way. It seems that it's possible to just run:
 
-    letsencrypt -c /etc/renewal/$domain.conf --renew-by-default
+    letsencrypt -c /etc/letsenctypt/renewal/$domain.conf --renew-by-default
+
+> --renew-by-default renews every time it's run; 
+> --keep-until-expiring instead waits until 30 days before expiry and 
+> renews then. I think that's the simpler approach, and the same
+> letsencrypt command line can then both obtain the original cert and renew
+> it. --[[Joey]]
 
  [letsencrypt.org gods]: https://letsencrypt.org
  [letsencrypt enters backports]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809018
@@ -91,3 +97,28 @@ Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets
  * 5 Certificates per Domain per week
  * 500 Registrations/IP address per 3 hours
  * 300 Pending Authorizations/Account per week
+
+---- 
+
+## how to only enable ssl once a certificate is available
+
+Tip from [[Joey]]:
+
+Letsencrypt has a bit of a chicken and egg problem, in that the http server
+has to be up to get the certificate, but the apache site config file
+has to contain both the http and the https vhost. And the https vhost needs
+to point to cert files not available until letsencrypt has run.
+
+smcv was thinking about dealing with that by generating a temporary
+self-signed cert first. But, I don't like the possibility that a http site
+would come up with such a cert during normal operation.
+
+I found a way around this when adding letsencrypt support to propellor:
+Make the apache site config file contain only the http vhost, and use
+IncludeOptional to include another file which contains the https vhost.
+Generate that file only once letsencrypt has generated the cert.
+
+Note that IncludeOptional has to be used with a wildcard to avoid it being
+an error if the included file doesn't exist. So, something like:
+
+	IncludeOptional /etc/apache2/sites-available/$domain/*.conf

another comment
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 8a3b1a9..5e70995 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -101,5 +101,18 @@ Oh, and this could be a [plugin][], not sure if that would make sense, but it's
 >> that seems promising. At the moment only letsencrypt is seems packaged
 >> in debian yet and that's the first bar. --[[Joey]]
 
->>> Agreed as well. Just scratching an itch here... The `acme` client looks interesting, but it's go, which brings a whole set of dependencies in. But I like its philosophy and it could integrate well. Also note that the above instructions fail to take into account the canonical and alias names of the site, which breaks openid logins... Something to fix in my future renewals... --[[anarcat]]
-
+>>> Agreed as well. Just scratching an itch here... The `acme`
+>>> client looks interesting, but it's go, which brings a whole set of
+>>> dependencies in. But I like its philosophy and it could integrate
+>>> well. Also note that the above instructions fail to take into account
+>>> the canonical and alias names of the site, which breaks openid
+>>> logins... Something to fix in my future renewals... --[[anarcat]]
+
+Here's an interesting [puppet implementation][] that mentions another (!)
+golang client ([lego][]), which has the interesting property of
+supporting DNS challenges. The puppet code itself uses the shell script
+previously mentioned. --[[anarcat]]
+
+ [puppet implementation]:
+ https://bzed.de/post/2016/02/bzed-letsencrypt_puppet_module/
+ [lego]: https://github.com/xenolf/lego

restructure
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index b40439a..8a3b1a9 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -1,6 +1,9 @@
 it would be great if, as part of the SSL integration, ikiwiki-hosting would call up on the [letsencrypt.org gods][] to install proper certs.
 
-so far I have done this by hand:
+First implementation
+--------------------
+
+so far I have done this by hand, using the main client:
 
 1. define some handy variables:
 
@@ -49,7 +52,8 @@ so far I have done this by hand:
 Ikiwiki hosting would need to perform steps 3 to 5, and probably have
 a `Recommends` on letsencrypt. -- [[anarcat]]
 
-Oh, and this could be a [plugin][], not sure if that would make sense, but it's the way it works on that side of the world.
+Potential clients
+-----------------
 
 Finally, note that there is now a fairly [large set of Let's Encrypt clients][], here's a short list (those have not been reviewed or tested for compatiblity with ikiwiki-hosting):
 
@@ -72,6 +76,21 @@ Also, renewals need to be processed in some way. It seems that it's possible to
  [letsacme]: https://github.com/neurobin/letsacme
  [acme-tiny]: https://github.com/diafygi/acme-tiny/
 
+Rate limits
+-----------
+
+Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets-encrypt/6769), they don't seem to be a problem unless you run a really huge site (500 registrations per 3 hours per IP!). The limits are:
+
+ * 100 Names/Certificate (how many domain names you can include in a single certificate)
+ * 5 Certificates per Domain per week
+ * 500 Registrations/IP address per 3 hours
+ * 300 Pending Authorizations/Account per week
+
+Discussion
+----------
+
+Oh, and this could be a [plugin][], not sure if that would make sense, but it's the way it works on that side of the world. --[[anarcat]]
+
 > I would much rather use something small enough to be reviewable, particularly if we're
 > going to have to run it unattended as root; the official Let's Encrypt client is *huge*.
 > We don't have to worry about portability to non-Debian environments or non-Apache
@@ -84,10 +103,3 @@ Also, renewals need to be processed in some way. It seems that it's possible to
 
 >>> Agreed as well. Just scratching an itch here... The `acme` client looks interesting, but it's go, which brings a whole set of dependencies in. But I like its philosophy and it could integrate well. Also note that the above instructions fail to take into account the canonical and alias names of the site, which breaks openid logins... Something to fix in my future renewals... --[[anarcat]]
 
-
-Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets-encrypt/6769), they don't seem to be a problem unless you run a really huge site (500 registrations per 3 hours per IP!). The limits are:
-
- * 100 Names/Certificate (how many domain names you can include in a single certificate)
- * 5 Certificates per Domain per week
- * 500 Registrations/IP address per 3 hours
- * 300 Pending Authorizations/Account per week

rate limits details, i personnally hit the 5 certs per domain per week while debugging this
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 4029ae4..b40439a 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -83,3 +83,11 @@ Also, renewals need to be processed in some way. It seems that it's possible to
 >> in debian yet and that's the first bar. --[[Joey]]
 
 >>> Agreed as well. Just scratching an itch here... The `acme` client looks interesting, but it's go, which brings a whole set of dependencies in. But I like its philosophy and it could integrate well. Also note that the above instructions fail to take into account the canonical and alias names of the site, which breaks openid logins... Something to fix in my future renewals... --[[anarcat]]
+
+
+Regarding [rate limits](https://community.letsencrypt.org/t/rate-limits-for-lets-encrypt/6769), they don't seem to be a problem unless you run a really huge site (500 registrations per 3 hours per IP!). The limits are:
+
+ * 100 Names/Certificate (how many domain names you can include in a single certificate)
+ * 5 Certificates per Domain per week
+ * 500 Registrations/IP address per 3 hours
+ * 300 Pending Authorizations/Account per week

renewals hint
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index d598bdb..4029ae4 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -58,7 +58,9 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
  * [acme][], root-less, more minimal implementation than the official client, in Go
  * [acme-tiny][] is a very small client (~200 lines of python code) that aims to be easily audited and to do only one thing well. for example, you need to generate your RSA key yourself (which may actually be a good thing considering how ikiwiki-hosting works)
 
-Also, renewals need to be processed in some way.
+Also, renewals need to be processed in some way. It seems that it's possible to just run:
+
+    letsencrypt -c /etc/renewal/$domain.conf --renew-by-default
 
  [letsencrypt.org gods]: https://letsencrypt.org
  [letsencrypt enters backports]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809018

not necessary: --server https://acme-v01.api.letsencrypt.org/directory
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 5d4a6e3..d598bdb 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -26,7 +26,6 @@ so far I have done this by hand:
         sudo -s
         source venv/bin/activate
         letsencrypt certonly --webroot \
-          --server https://acme-v01.api.letsencrypt.org/directory \
           --agree-dev-preview --agree-tos \
           --webroot-path="$webroot" \
           --domains $domain --email $email

fix formatting
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index b5fa2ce..5d4a6e3 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -4,10 +4,10 @@ so far I have done this by hand:
 
 1. define some handy variables:
 
-    domain=example.com
-    email=nobody@$domain
-    username=w-example
-    webroot=/home/$username/public_html/
+        domain=example.com
+        email=nobody@$domain
+        username=w-example
+        webroot=/home/$username/public_html/
 
 2. install the letsencrypt client software:
 

more alternatives
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index a992166..b5fa2ce 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -57,6 +57,7 @@ Finally, note that there is now a fairly [large set of Let's Encrypt clients][],
  * [letsencrypt.sh][], bash-only client that could work in Wheezy
  * [simp_le][], much simpler implementation in Python
  * [acme][], root-less, more minimal implementation than the official client, in Go
+ * [acme-tiny][] is a very small client (~200 lines of python code) that aims to be easily audited and to do only one thing well. for example, you need to generate your RSA key yourself (which may actually be a good thing considering how ikiwiki-hosting works)
 
 Also, renewals need to be processed in some way.
 
@@ -67,6 +68,8 @@ Also, renewals need to be processed in some way.
  [simp_le]: https://github.com/kuba/simp_le
  [letsencrypt.sh]: https://github.com/lukas2511/letsencrypt.sh
  [acme]: https://github.com/hlandau/acme
+ [letsacme]: https://github.com/neurobin/letsacme
+ [acme-tiny]: https://github.com/diafygi/acme-tiny/
 
 > I would much rather use something small enough to be reviewable, particularly if we're
 > going to have to run it unattended as root; the official Let's Encrypt client is *huge*.

make the LE instructions closer to a working script to ease copy-paste
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 2b65d5b..a992166 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -2,6 +2,13 @@ it would be great if, as part of the SSL integration, ikiwiki-hosting would call
 
 so far I have done this by hand:
 
+1. define some handy variables:
+
+    domain=example.com
+    email=nobody@$domain
+    username=w-example
+    webroot=/home/$username/public_html/
+
 2. install the letsencrypt client software:
 
    * if you are on Debian sid, stretch (or when [letsencrypt enters backports][]):
@@ -21,8 +28,8 @@ so far I have done this by hand:
         letsencrypt certonly --webroot \
           --server https://acme-v01.api.letsencrypt.org/directory \
           --agree-dev-preview --agree-tos \
-          --webroot-path=/home/w-example/public_html/ \
-          --domains example.com --email nobody@example.com
+          --webroot-path="$webroot" \
+          --domains $domain --email $email
 
     ... notice how you need to change the two last lines for your
     environment.
@@ -31,13 +38,13 @@ so far I have done this by hand:
       `/etc/letsencrypt/live/example.com`. install it where ikiwiki
       expects it:
 
-        ln -s /etc/letsencrypt/live/example.com/cert.pem /etc/ikiwiki-hosting/config/w-example/ssl.crt
-        ln -s /etc/letsencrypt/live/example.com/fullchain.pem /etc/ikiwiki-hosting/config/w-example/ssl.chain
-        ln -s /etc/letsencrypt/live/example.com/privkey.pem /etc/ikiwiki-hosting/config/w-example/ssl.key
+        ln -s /etc/letsencrypt/live/$domain/cert.pem /etc/ikiwiki-hosting/config/$username/ssl.crt
+        ln -s /etc/letsencrypt/live/$domain/fullchain.pem /etc/ikiwiki-hosting/config/$username/ssl.chain
+        ln -s /etc/letsencrypt/live/$domain/privkey.pem /etc/ikiwiki-hosting/config/$username/ssl.key
 
 5. regenerate the apache configs and restart apache:
 
-        ikisite enable example.com
+        ikisite enable $domain
         service apache2 reload # or restart?
 
 Ikiwiki hosting would need to perform steps 3 to 5, and probably have

announce 0.20160123, fixing a bad bug in 0.20160121 (sorry!)
diff --git a/doc/news/version_0.20160123.mdwn b/doc/news/version_0.20160123.mdwn
new file mode 100644
index 0000000..755642f
--- /dev/null
+++ b/doc/news/version_0.20160123.mdwn
@@ -0,0 +1,4 @@
+ikiwiki-hosting 0.20160123 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix the escaping of `{` in HostingAutomator by also escaping the `}`,
+     fixing a regression that broke `ikisite create`"""]]

redo the list and mention aliases
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 8000726..2b65d5b 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -45,16 +45,21 @@ a `Recommends` on letsencrypt. -- [[anarcat]]
 
 Oh, and this could be a [plugin][], not sure if that would make sense, but it's the way it works on that side of the world.
 
-Finally, note that there is now a fairly [large set of Let's Encrypt clients][]. For example, there is a [bash-only client][] that could work in Wheezy and a [much simpler implementation in Python][]. Those have not been reviewed or tested for compatiblity with ikiwiki-hosting however.
+Finally, note that there is now a fairly [large set of Let's Encrypt clients][], here's a short list (those have not been reviewed or tested for compatiblity with ikiwiki-hosting):
+
+ * [letsencrypt.sh][], bash-only client that could work in Wheezy
+ * [simp_le][], much simpler implementation in Python
+ * [acme][], root-less, more minimal implementation than the official client, in Go
 
 Also, renewals need to be processed in some way.
 
  [letsencrypt.org gods]: https://letsencrypt.org
  [letsencrypt enters backports]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809018
  [plugin]: https://github.com/letsencrypt/letsencrypt/wiki/Plugins
- [bash-only client]: https://github.com/lukas2511/letsencrypt.sh
  [large set of Let's Encrypt clients]: https://community.letsencrypt.org/t/list-of-client-implementations/2103
- [much simpler implementation in Python]: https://github.com/kuba/simp_le
+ [simp_le]: https://github.com/kuba/simp_le
+ [letsencrypt.sh]: https://github.com/lukas2511/letsencrypt.sh
+ [acme]: https://github.com/hlandau/acme
 
 > I would much rather use something small enough to be reviewable, particularly if we're
 > going to have to run it unattended as root; the official Let's Encrypt client is *huge*.
@@ -65,3 +70,5 @@ Also, renewals need to be processed in some way.
 >> than overall code size. <https://github.com/hlandau/acme> is one client
 >> that seems promising. At the moment only letsencrypt is seems packaged
 >> in debian yet and that's the first bar. --[[Joey]]
+
+>>> Agreed as well. Just scratching an itch here... The `acme` client looks interesting, but it's go, which brings a whole set of dependencies in. But I like its philosophy and it could integrate well. Also note that the above instructions fail to take into account the canonical and alias names of the site, which breaks openid logins... Something to fix in my future renewals... --[[anarcat]]

comment
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 9ef6f9b..8000726 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -60,3 +60,8 @@ Also, renewals need to be processed in some way.
 > going to have to run it unattended as root; the official Let's Encrypt client is *huge*.
 > We don't have to worry about portability to non-Debian environments or non-Apache
 > web servers, which takes away a lot of the reason to use something so big. --smcv
+
+>> Kind of agreed, but I'm more interested in ameanability to automation
+>> than overall code size. <https://github.com/hlandau/acme> is one client
+>> that seems promising. At the moment only letsencrypt is seems packaged
+>> in debian yet and that's the first bar. --[[Joey]]

create my userpage (copied from ikiwiki.info)
diff --git a/doc/users/smcv.mdwn b/doc/users/smcv.mdwn
new file mode 100644
index 0000000..e9d68cd
--- /dev/null
+++ b/doc/users/smcv.mdwn
@@ -0,0 +1,8 @@
+Website: <https://www.pseudorandom.co.uk/>
+
+Blog: <https://smcv.pseudorandom.co.uk/>
+
+My repository containing ikiwiki-hosting branches:
+
+* gitweb: <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git>
+* anongit: <git://git.pseudorandom.co.uk/git/smcv/ikiwiki-hosting.git>

let's have news and a feed for this wiki too
diff --git a/doc/index.mdwn b/doc/index.mdwn
index 0b27aef..1a240a0 100644
--- a/doc/index.mdwn
+++ b/doc/index.mdwn
@@ -3,6 +3,7 @@ interface for [Branchable](http://branchable.com/).
 
 Stuff here:
 
+* [[news]]
 * [[TODO]]
 * [[bugs]]
 * [[security]]
diff --git a/doc/news.mdwn b/doc/news.mdwn
new file mode 100644
index 0000000..7667891
--- /dev/null
+++ b/doc/news.mdwn
@@ -0,0 +1 @@
+[[!inline pages="news/* and !news/*/* and !news/discussion" rss=no atom=yes rootpage="news" show=5]]
diff --git a/doc/news/version_0.20160121.mdwn b/doc/news/version_0.20160121.mdwn
new file mode 100644
index 0000000..cb872eb
--- /dev/null
+++ b/doc/news/version_0.20160121.mdwn
@@ -0,0 +1,15 @@
+ikiwiki-hosting 0.20160121 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+ * [ [[Joey Hess|joey]] ]
+   * Fix looping redirection when `redirect_to_https` is set.
+     Thanks, [[Antoine Beaupré|anarcat]].
+   * controlpanel: Display unfocused site buttons with low opacity, but still
+     display them. This is an accessability fix; the old hiding method broken
+     caret browsing and screenreaders.
+ * [ [[Simon McVittie|smcv]] ]
+   * d/control: use https for Homepage
+   * d/control: use pkg-perl autopkgtest setup
+   * Fix "unescaped left brace in regex is deprecated" with Perl 5.22
+   * Normalize packaging through `wrap-and-sort -abst`
+   * Depend on libimage-magick-perl in preference to transitional
+     perlmagick package, similar to [#789221](https://bugs.debian.org/789221) in ikiwiki"""]]

I would prefer not to depend on the (huge) reference Let's Encrypt client
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 0c7a381..9ef6f9b 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -55,3 +55,8 @@ Also, renewals need to be processed in some way.
  [bash-only client]: https://github.com/lukas2511/letsencrypt.sh
  [large set of Let's Encrypt clients]: https://community.letsencrypt.org/t/list-of-client-implementations/2103
  [much simpler implementation in Python]: https://github.com/kuba/simp_le
+
+> I would much rather use something small enough to be reviewable, particularly if we're
+> going to have to run it unattended as root; the official Let's Encrypt client is *huge*.
+> We don't have to worry about portability to non-Debian environments or non-Apache
+> web servers, which takes away a lot of the reason to use something so big. --smcv

add renewals and other clients.
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 11050a1..0c7a381 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -4,7 +4,7 @@ so far I have done this by hand:
 
 2. install the letsencrypt client software:
 
-   * if you are on Debian sid, stretch (or when [letsencrypt enters backports](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809018):
+   * if you are on Debian sid, stretch (or when [letsencrypt enters backports][]):
 
             apt install letsencrypt
 
@@ -43,8 +43,15 @@ so far I have done this by hand:
 Ikiwiki hosting would need to perform steps 3 to 5, and probably have
 a `Recommends` on letsencrypt. -- [[anarcat]]
 
-Oh, and this could be a [plugin](https://github.com/letsencrypt/letsencrypt/wiki/Plugins), not sure if that would make sense, but it's the way it works on that side of the world.
+Oh, and this could be a [plugin][], not sure if that would make sense, but it's the way it works on that side of the world.
+
+Finally, note that there is now a fairly [large set of Let's Encrypt clients][]. For example, there is a [bash-only client][] that could work in Wheezy and a [much simpler implementation in Python][]. Those have not been reviewed or tested for compatiblity with ikiwiki-hosting however.
+
+Also, renewals need to be processed in some way.
 
- [go public on 2015-12-03]: https://letsencrypt.org/2015/11/12/public-beta-timing.html
- [google docs to request a whitelist]: https://docs.google.com/a/letsencrypt.org/forms/d/15Ucm4A20y2rf9gySCTXD6yoLG6Tba7AwYgglV7CKHmM
  [letsencrypt.org gods]: https://letsencrypt.org
+ [letsencrypt enters backports]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809018
+ [plugin]: https://github.com/letsencrypt/letsencrypt/wiki/Plugins
+ [bash-only client]: https://github.com/lukas2511/letsencrypt.sh
+ [large set of Let's Encrypt clients]: https://community.letsencrypt.org/t/list-of-client-implementations/2103
+ [much simpler implementation in Python]: https://github.com/kuba/simp_le

beta now public, it's in stretch, and backport underway
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 6ee9863..11050a1 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -2,13 +2,9 @@ it would be great if, as part of the SSL integration, ikiwiki-hosting would call
 
 so far I have done this by hand:
 
-1. register on their beta using the
-   [google docs to request a whitelist][] (shouldn't be necessary
-   after they [go public on 2015-12-03][])
-
 2. install the letsencrypt client software:
 
-   * if you are on Debian sid:
+   * if you are on Debian sid, stretch (or when [letsencrypt enters backports](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809018):
 
             apt install letsencrypt
 

close
diff --git a/doc/bugs/accessability_problem_with_control_panel.mdwn b/doc/bugs/accessability_problem_with_control_panel.mdwn
index 9a07bb9..b451094 100644
--- a/doc/bugs/accessability_problem_with_control_panel.mdwn
+++ b/doc/bugs/accessability_problem_with_control_panel.mdwn
@@ -13,6 +13,6 @@ than accessability, but still seems there should be a way to get both.
 Note that the control panel is designed to work when javascript is
 disabled. The buttons default to visible until javascript hides them.
 
-Possble fix: Instead of totally hiding these buttons, display them with a
-low opacity. So screen readers can still speak them.
+fix: Instead of totally hiding these buttons, display them with a
+low opacity. So screen readers can still speak them. [[done]]
 --[[Joey]]

controlpanel: Display unfocused site buttons with low opacity, but still display them. This is an accessability fix; the old hiding method broken caret browsing and screenreaders.
diff --git a/debian/changelog b/debian/changelog
index 335e885..048ec42 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,9 @@ ikiwiki-hosting (0.20150615) UNRELEASED; urgency=medium
 
   * Fix looping redirection when redirect_to_https is set.
     Thanks, Antoine Beaupré.
+  * controlpanel: Display unfocused site buttons with low opacity, but still
+    display them. This is an accessability fix; the old hiding method broken
+    caret browsing and screenreaders.
 
  -- Joey Hess <id@joeyh.name>  Sat, 21 Nov 2015 14:13:01 -0400
 
diff --git a/doc/bugs/accessability_problem_with_control_panel.mdwn b/doc/bugs/accessability_problem_with_control_panel.mdwn
index 82cc48a..9a07bb9 100644
--- a/doc/bugs/accessability_problem_with_control_panel.mdwn
+++ b/doc/bugs/accessability_problem_with_control_panel.mdwn
@@ -1,7 +1,18 @@
 Report from blind user, was unable to find delete button for sites on the
 control panel.
 
-Probably because the CSS only makes buttons to manage a site visible when
+Probably because the javascript only makes buttons to manage a site visible when
 the mouse is hovering over that site in the list. When I turn on caret
 browsing and use arrow keys to move over sites, I experience the same
-problem. --[[Joey]]
+problem.
+
+The point of the CSS is to reduce visual clutter with the several buttons
+per site.. That is less important
+than accessability, but still seems there should be a way to get both.
+
+Note that the control panel is designed to work when javascript is
+disabled. The buttons default to visible until javascript hides them.
+
+Possble fix: Instead of totally hiding these buttons, display them with a
+low opacity. So screen readers can still speak them.
+--[[Joey]]
diff --git a/templates/controlpanel.tmpl b/templates/controlpanel.tmpl
index f227d2b..f982428 100644
--- a/templates/controlpanel.tmpl
+++ b/templates/controlpanel.tmpl
@@ -33,11 +33,11 @@
 <script type="text/javascript">
 function highlight(elt, class) {
 	elt.bgColor='#e0f5c3';
-	document.getElementById(class).style.display="inline";
+	document.getElementById(class).style.opacity=1.0;
 }
 
 function unhighlight(elt, class) {
-	document.getElementById(class).style.display="none";
+	document.getElementById(class).style.opacity=0.1;
 	elt.bgColor='white';
 }
 
@@ -45,7 +45,7 @@ function unhighlight(elt, class) {
 function hideall() {
 	hideableElements = getElementsByClass('hideable');
 	for (var i = 0; i < hideableElements.length; i++) {
-		hideableElements[i].style.display="none";
+		hideableElements[i].style.opacity=0.1;
 	}
 }
 hook("onload", hideall);

update
diff --git a/doc/bugs/accessability_problem_with_control_panel.mdwn b/doc/bugs/accessability_problem_with_control_panel.mdwn
index 421f877..82cc48a 100644
--- a/doc/bugs/accessability_problem_with_control_panel.mdwn
+++ b/doc/bugs/accessability_problem_with_control_panel.mdwn
@@ -2,4 +2,6 @@ Report from blind user, was unable to find delete button for sites on the
 control panel.
 
 Probably because the CSS only makes buttons to manage a site visible when
-the mouse is hovering over that site in the list. --[[Joey]]
+the mouse is hovering over that site in the list. When I turn on caret
+browsing and use arrow keys to move over sites, I experience the same
+problem. --[[Joey]]

bug report
diff --git a/doc/bugs/accessability_problem_with_control_panel.mdwn b/doc/bugs/accessability_problem_with_control_panel.mdwn
new file mode 100644
index 0000000..421f877
--- /dev/null
+++ b/doc/bugs/accessability_problem_with_control_panel.mdwn
@@ -0,0 +1,5 @@
+Report from blind user, was unable to find delete button for sites on the
+control panel.
+
+Probably because the CSS only makes buttons to manage a site visible when
+the mouse is hovering over that site in the list. --[[Joey]]

close
diff --git a/debian/changelog b/debian/changelog
index c8b873d..335e885 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+ikiwiki-hosting (0.20150615) UNRELEASED; urgency=medium
+
+  * Fix looping redirection when redirect_to_https is set.
+    Thanks, Antoine Beaupré.
+
+ -- Joey Hess <id@joeyh.name>  Sat, 21 Nov 2015 14:13:01 -0400
+
 ikiwiki-hosting (0.20150614) unstable; urgency=medium
 
   [ Joey Hess ]
diff --git a/doc/bugs/ssl_redirection_infinite_loop.mdwn b/doc/bugs/ssl_redirection_infinite_loop.mdwn
index 7b601d9..9a8e772 100644
--- a/doc/bugs/ssl_redirection_infinite_loop.mdwn
+++ b/doc/bugs/ssl_redirection_infinite_loop.mdwn
@@ -56,3 +56,5 @@ index 58e8697..7823b87 100644
 </pre>
 
 works in production in http://anarc.at/ (encrypted with letsencrypt!). -- [[anarcat]]
+
+> [[applied|done]] --[[Joey]]

comment
diff --git a/doc/todo/letsencrypt_support/comment_1_4497b4b6dfd7bcb77bc1e6dac5761f7e._comment b/doc/todo/letsencrypt_support/comment_1_4497b4b6dfd7bcb77bc1e6dac5761f7e._comment
new file mode 100644
index 0000000..305566c
--- /dev/null
+++ b/doc/todo/letsencrypt_support/comment_1_4497b4b6dfd7bcb77bc1e6dac5761f7e._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2015-11-21T17:38:02Z"
+ content="""
+I definitely want ikiwiki-hosting to support letsencrypt.
+
+It's important that any support includes automated certificate renewals.
+Either by letting the letsencrypt client set things up in a way it can
+later handle renewal of itself, or by having ikiwiki-hosting take care of
+it.
+
+Also, there is rate limiting in the current beta (a few domains per IP or
+something like that), and there may well be rate limiting post-beta. So
+initial request may fail and a site be left in http-only mode. Probably
+calls for a cron job to retry any sites that don't yet have a certificate.
+"""]]

mention letsencrypt plugins
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
index 8bbd4c7..6ee9863 100644
--- a/doc/todo/letsencrypt_support.mdwn
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -35,9 +35,9 @@ so far I have done this by hand:
       `/etc/letsencrypt/live/example.com`. install it where ikiwiki
       expects it:
 
-        ln -s /etc/letsencrypt/live/example.com/cert.pem ikiwiki-hosting/config/w-example/ssl.crt
-        ln -s /etc/letsencrypt/live/example.com/fullchain.pem ikiwiki-hosting/config/w-example/ssl.chain
-        ln -s /etc/letsencrypt/live/example.com/privkey.pem ikiwiki-hosting/config/w-example/ssl.key
+        ln -s /etc/letsencrypt/live/example.com/cert.pem /etc/ikiwiki-hosting/config/w-example/ssl.crt
+        ln -s /etc/letsencrypt/live/example.com/fullchain.pem /etc/ikiwiki-hosting/config/w-example/ssl.chain
+        ln -s /etc/letsencrypt/live/example.com/privkey.pem /etc/ikiwiki-hosting/config/w-example/ssl.key
 
 5. regenerate the apache configs and restart apache:
 
@@ -47,6 +47,8 @@ so far I have done this by hand:
 Ikiwiki hosting would need to perform steps 3 to 5, and probably have
 a `Recommends` on letsencrypt. -- [[anarcat]]
 
+Oh, and this could be a [plugin](https://github.com/letsencrypt/letsencrypt/wiki/Plugins), not sure if that would make sense, but it's the way it works on that side of the world.
+
  [go public on 2015-12-03]: https://letsencrypt.org/2015/11/12/public-beta-timing.html
  [google docs to request a whitelist]: https://docs.google.com/a/letsencrypt.org/forms/d/15Ucm4A20y2rf9gySCTXD6yoLG6Tba7AwYgglV7CKHmM
  [letsencrypt.org gods]: https://letsencrypt.org

letsencrypt todo and instructions/workaround
diff --git a/doc/todo/letsencrypt_support.mdwn b/doc/todo/letsencrypt_support.mdwn
new file mode 100644
index 0000000..8bbd4c7
--- /dev/null
+++ b/doc/todo/letsencrypt_support.mdwn
@@ -0,0 +1,52 @@
+it would be great if, as part of the SSL integration, ikiwiki-hosting would call up on the [letsencrypt.org gods][] to install proper certs.
+
+so far I have done this by hand:
+
+1. register on their beta using the
+   [google docs to request a whitelist][] (shouldn't be necessary
+   after they [go public on 2015-12-03][])
+
+2. install the letsencrypt client software:
+
+   * if you are on Debian sid:
+
+            apt install letsencrypt
+
+   * otherwise, run the magic commands:
+
+            git clone https://github.com/letsencrypt/letsencrypt
+            cd letsencrypt
+            ./letsencrypt-auto --server https://acme-v01.api.letsencrypt.org/directory --help
+
+3. request a certificate:
+
+        sudo -s
+        source venv/bin/activate
+        letsencrypt certonly --webroot \
+          --server https://acme-v01.api.letsencrypt.org/directory \
+          --agree-dev-preview --agree-tos \
+          --webroot-path=/home/w-example/public_html/ \
+          --domains example.com --email nobody@example.com
+
+    ... notice how you need to change the two last lines for your
+    environment.
+
+4. this will create a certificate in
+      `/etc/letsencrypt/live/example.com`. install it where ikiwiki
+      expects it:
+
+        ln -s /etc/letsencrypt/live/example.com/cert.pem ikiwiki-hosting/config/w-example/ssl.crt
+        ln -s /etc/letsencrypt/live/example.com/fullchain.pem ikiwiki-hosting/config/w-example/ssl.chain
+        ln -s /etc/letsencrypt/live/example.com/privkey.pem ikiwiki-hosting/config/w-example/ssl.key
+
+5. regenerate the apache configs and restart apache:
+
+        ikisite enable example.com
+        service apache2 reload # or restart?
+
+Ikiwiki hosting would need to perform steps 3 to 5, and probably have
+a `Recommends` on letsencrypt. -- [[anarcat]]
+
+ [go public on 2015-12-03]: https://letsencrypt.org/2015/11/12/public-beta-timing.html
+ [google docs to request a whitelist]: https://docs.google.com/a/letsencrypt.org/forms/d/15Ucm4A20y2rf9gySCTXD6yoLG6Tba7AwYgglV7CKHmM
+ [letsencrypt.org gods]: https://letsencrypt.org

there's a bug in the ssl redirection code
diff --git a/doc/bugs/ssl_redirection_infinite_loop.mdwn b/doc/bugs/ssl_redirection_infinite_loop.mdwn
new file mode 100644
index 0000000..7b601d9
--- /dev/null
+++ b/doc/bugs/ssl_redirection_infinite_loop.mdwn
@@ -0,0 +1,58 @@
+this is a [[patch]], really, with full description builtin:
+
+<pre>
+From 8f16b20818a14f27bb18aa3016d5808dd56082c9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20Beaupr=C3=A9?= <anarcat@koumbit.org>
+Date: Wed, 18 Nov 2015 23:08:10 -0500
+Subject: [PATCH] fix ssl redirections
+
+it seems the previous redirections were not doing anything, or more
+precisely, they were looping:
+
+    RewriteRule ^/(.*) <TMPL_VAR URL_ESCAPED> [L,R,NE]
+
+... was generting the following rule:
+
+    RewriteRule ^/(.*)  [L,R,NE]
+
+because url_escaped wasn't passed to the template. but even if was, it
+would still do an infinite redirect loop on itself. what it needs is
+https_url_escaped, which wasn't passed either.
+---
+ ikisite                    | 4 ++++
+ templates/apache-site.tmpl | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/ikisite b/ikisite
+index 9197ca3..a847c20 100755
+--- a/ikisite
++++ b/ikisite
+@@ -1621,6 +1621,10 @@ sub enable {
+                cgidir => cgidir($hostname),
+                logdir => logdir($hostname),
+                source_hostname => "source.$hostname",
++               # Value escaped to prevent leakage
++               # into RewriteEngine regexp.
++               url_escaped => quotemeta($redirurl),
++               https_url_escaped => quotemeta($httpsredirurl),
+                @ssl_template_vars
+        );
+
+diff --git a/templates/apache-site.tmpl b/templates/apache-site.tmpl
+index 58e8697..7823b87 100644
+--- a/templates/apache-site.tmpl
++++ b/templates/apache-site.tmpl
+@@ -15,7 +15,7 @@
+
+ <TMPL_IF REDIRECT_TO_HTTPS>
+        RewriteEngine On
+-       RewriteRule ^/(.*) <TMPL_VAR URL_ESCAPED>$1 [L,R,NE]
++       RewriteRule ^/(.*) <TMPL_VAR HTTPS_URL_ESCAPED>$1 [L,R,NE]
+ <TMPL_ELSE>
+        DocumentRoot <TMPL_VAR DESTDIR>
+        <Directory />
+--
+2.1.4
+</pre>
+
+works in production in http://anarc.at/ (encrypted with letsencrypt!). -- [[anarcat]]

describe how the https redirect works
diff --git a/doc/design/apacheconfig.mdwn b/doc/design/apacheconfig.mdwn
index 2e71337..6e68397 100644
--- a/doc/design/apacheconfig.mdwn
+++ b/doc/design/apacheconfig.mdwn
@@ -55,6 +55,10 @@ of the site but not the normal version (enabling HTTP authentication
 for [[!iki plugins/httpauth desc="the httpauth plugin"]], perhaps),
 put it in `/etc/ikiwiki-hosting/config/$username/apache-ssl.conf.tmpl`.
 
+If you want to redirect the plain text (HTTP) site to the SSL version
+(HTTPS), you want to check the `redirect from http to https?` option
+in the config page, or `redirect_to_https` option in the `.setup` file.
+
 ---
 
 Special configuration for the `source.$hostname.$domain` (gitweb)

Added support for emailauth.
Untested!
diff --git a/IkiWiki/Business.pm b/IkiWiki/Business.pm
index 3a37b5c..ff90a8c 100644
--- a/IkiWiki/Business.pm
+++ b/IkiWiki/Business.pm
@@ -52,16 +52,16 @@ sub planinfo ($) {
 # be assumed to exist whether or not it really does.
 # (Maybe this site is being created.)
 sub suggestedplan ($;$) {
-	my $openid=shift;
+	my $username=shift;
 	my $assumesite=shift;
 
 	return undef unless %plans;
 
-	my $currentsites=currentsites($openid, $assumesite);
+	my $currentsites=currentsites($username, $assumesite);
 	my @candidate_plans=sortprice(grep { 
 		$plans{$_}{active} &&
 		$plans{$_}{maxsites} >= $currentsites
-	} upgradeset($openid, 1));
+	} upgradeset($username, 1));
 	return $candidate_plans[0] if @candidate_plans;
 
 	# just in case, fallback to the default plan.
@@ -74,13 +74,13 @@ sub suggestedplan ($;$) {
 # Returns true if the user needs to change from their current plan
 # to cover their sites. (Of if the user has no current plan.)
 sub needchangeplan ($;$) {
-	my $openid=shift;
+	my $username=shift;
 	my $assumesite=shift;
 	
 	return 0 unless %plans;
 
-	my $currentsites=currentsites($openid, $assumesite);
-	my $currentplan=currentplan($openid);
+	my $currentsites=currentsites($username, $assumesite);
+	my $currentplan=currentplan($username);
 	return 1 unless defined $currentplan;
 	if ($plans{$currentplan}{maxsites} < $currentsites) {
 		return 1;
@@ -93,13 +93,13 @@ sub needchangeplan ($;$) {
 # Returns the current price plan for a user.
 # Returns undef if the user is not currently enrolled in a plan.
 sub currentplan ($) {
-	my $openid=shift;
+	my $username=shift;
 	return undef unless %plans;
 
 	eval q{use IkiWiki::Customer};
 	die $@ if $@;
 	
-	my $plan=IkiWiki::Customer::customer_get($openid, "currentplan");
+	my $plan=IkiWiki::Customer::customer_get($username, "currentplan");
 	return $plan;
 }
 
@@ -108,24 +108,25 @@ sub currentplan ($) {
 my $currentsites_cache;
 my $currentsites_cache_owner;
 sub currentsites ($;$) {
-	my $openid=shift;
+	my $username=shift;
 	my $assumesite=shift;
 
 	my @owned;
 	if (defined $currentsites_cache_owner &&
-	    $currentsites_cache_owner eq $openid) {
+	    $currentsites_cache_owner eq $username) {
 		@owned=@$currentsites_cache;
 	}
 	else {
-		# A single user may have multiple openids.
+		# A single user may have multiple openids and emails
+		# used in sites they own.
 		eval q{use IkiWiki::Customer};
 		die $@ if $@;
-		my @openids=IkiWiki::Customer::openid_list($openid);
+		my @accounts=IkiWiki::Customer::account_list($username);
 
 		@owned=split(' ', IkiWiki::Hosting::getshell("ikisite-wrapper",
-			"list", map {"--owner=$_"} @openids));
+			"list", map {"--owner=$_"} @accounts));
 		$currentsites_cache=\@owned;
-		$currentsites_cache_owner=$openid;
+		$currentsites_cache_owner=$username;
 	}
 
 	if (defined $assumesite) {
@@ -138,14 +139,14 @@ sub currentsites ($;$) {
 # Given a user, returns how many additional sites they can make, under
 # their current plan.
 sub sitesavailable ($) {
-	my $openid=shift;
+	my $username=shift;
 	
 	return undef unless %plans;
 
-	my $currentplan=currentplan($openid);
+	my $currentplan=currentplan($username);
 	return 0 unless defined $currentplan;
 	my $maxsites=$plans{$currentplan}{maxsites};
-	my @currentsites=currentsites($openid);
+	my @currentsites=currentsites($username);
 
 	if (@currentsites > $maxsites) {
 		# could happen if user's plan was downgraded, or something
@@ -158,12 +159,12 @@ sub sitesavailable ($) {
 
 # Given a user, returns the set of plans the user could upgrade to.
 sub upgradeset ($;$) {
-	my $openid=shift;
+	my $username=shift;
 	my $includecurrent=shift;
 	
 	return () unless %plans;
 
-	my $currentplan=currentplan($openid);
+	my $currentplan=currentplan($username);
 	if (! defined $currentplan) {
 		return keys %plans;
 	}
@@ -202,12 +203,12 @@ sub monthfrom ($;$) {
 
 # Returns when the next bill should be sent for a user.
 sub nextbilldate ($) {
-	my $openid=shift;
+	my $username=shift;
 	
 	eval q{use IkiWiki::Customer};
 	die $@ if $@;
 
-	my $bill_enddate=IkiWiki::Customer::customer_get($openid, "bill_enddate");
+	my $bill_enddate=IkiWiki::Customer::customer_get($username, "bill_enddate");
 	if (! defined $bill_enddate) {
 		# no bill sent yet; one should be sent immediatly
 		return time;
@@ -220,16 +221,16 @@ sub nextbilldate ($) {
 
 # Checks if it's time to send a reminder bill to a user.
 sub billreminderdue ($) {
-	my $openid=shift;
+	my $username=shift;
 	
 	eval q{use IkiWiki::Customer};
 	die $@ if $@;
 	
-	my $balance=IkiWiki::Customer::customer_get($openid, "balance");
+	my $balance=IkiWiki::Customer::customer_get($username, "balance");
 	if (! defined $balance || $balance <= 0) {
 		return 0;
 	}
-	my $lastbilldate=IkiWiki::Customer::customer_get($openid, "lastbilldate");
+	my $lastbilldate=IkiWiki::Customer::customer_get($username, "lastbilldate");
 	if (! defined $lastbilldate) {
 		# Customer has never been billed, so no reminder is due.
 		return 0;
@@ -244,7 +245,7 @@ sub billreminderdue ($) {
 	
 	return 0 if time < $when; # not due yet
 
-	my $lastreminderdate=IkiWiki::Customer::customer_get($openid, "lastreminderdate");
+	my $lastreminderdate=IkiWiki::Customer::customer_get($username, "lastreminderdate");
 	if (defined $lastreminderdate && $lastreminderdate >= $when) {
 		# Bill reminder has already been sent.
 		return 0;
@@ -266,7 +267,7 @@ sub currmonth () {
 # Invoice ids are of the form: BR-001/2010;
 # the invoice numbering resets at the start of each year.
 sub geninvoiceid ($;$) {
-	my $openid=shift;
+	my $username=shift;
 	my $dry_run=shift;
 	
 	my $invoice = IkiWiki::Customer::dir_get("invoice", "last");
@@ -297,14 +298,14 @@ sub geninvoiceid ($;$) {
 # Invoice BR-XXX/YYYY is stored in the customersite, in the file
 # invoice/YYYY-MM/BR-XXX.
 sub saveinvoice ($$$$) {
-	my $openid=shift;
+	my $username=shift;
 	my $invoicetext=shift;
 	my $dry_run=shift;
 	my $overwrite=shift;
 
 	return if $dry_run;
 	
-	my $invoiceid=IkiWiki::Customer::customer_get($openid, "lastinvoiceid");
+	my $invoiceid=IkiWiki::Customer::customer_get($username, "lastinvoiceid");
 	if (! defined $invoiceid) {
 		die "saveinvoice: failed to find lastinvoiceid";
 	}
@@ -344,37 +345,37 @@ sub saveinvoice ($$$$) {
 # user. Throws an error if the customer should be billed, but cannot
 # due to some problem.
 sub bill ($$;$) {
-	my $openid=shift;
+	my $username=shift;
 	my $template=shift;
 	my $dry_run=shift;

(Diff truncated)
figured out that thing...
diff --git a/doc/todo/git-annex_support.mdwn b/doc/todo/git-annex_support.mdwn
index 70980bf..febcd82 100644
--- a/doc/todo/git-annex_support.mdwn
+++ b/doc/todo/git-annex_support.mdwn
@@ -7,4 +7,78 @@ fatal: unrecognized command 'git-annex-shell '/home/w-...''
 
 The client then sets the `annex-ignore` variable and ignores that remote. And of course we'd also need [ikiwiki itself to support git-annex](https://ikiwiki.info/todo/git-annex_support/) but that's another story - at least allowing uploads would be a nice start.
 
-The workaround, of course, is to set `git-annex-shell` as the command in the `authorized_keys` file instead of `iki-git-shell`... -- [[anarcat]]
+The workaround, of course, is to set `git-annex-shell` as the command in the `authorized_keys` file instead of `iki-git-shell`... but that doesn't quite work because the remote URLs change completely.
+
+So one solution is to exploit the `git-shell-commands` extension of `git-shell`, which allows running arbitrary commands from `git-shell`. Since `git-annex` starts with `git`, it will clear the `iki-git-shell` checks - but it fails in `git-shell` because it's not a recognized git command. To fix this, we need to add the following script in `$HOME/git-shell-commands/git-annex-shell`:
+
+<pre>
+#!/usr/bin/python
+
+import os
+import re
+import shlex
+import sys
+
+try:
+    # original command is like:
+    # "git-annex-shell 'configlist' '/'"
+    # argv is expected to be:
+    # ['git-shell-commands/git-annex-shell', '/home/.../source.git/']
+    # the last argument is the sanitized repo path from iki-git-shell
+    # so parse the original command string into an array safely
+    orig_argv = shlex.split(os.environ['SSH_ORIGINAL_COMMAND'])
+    # construct the command with the original command and the safe repo path
+    cmd = ['git-annex-shell', '-c', orig_argv[1], sys.argv[1]]
+    # if we have more arguments, shove them in (skipping unsafe path)
+    cmd += orig_argv[3:]
+    # restrict git-shell to known commands
+    os.environ['GIT_ANNEX_SHELL_LIMITED'] = 'true'
+    # restrict git-annex to the sanitized repository
+    os.environ['GIT_ANNEX_SHELL_DIRECTORY'] = sys.argv[1]
+    # keep all commands as readonly, disabled
+    #os.environ['GIT_ANNEX_SHELL_READONLY'] = 'true'
+    # split into that new command
+    os.execlp('git-annex-shell', *cmd)
+except Exception as e:
+    print "git-annex-shell wrapper improperly called: %s" % e
+</pre>
+
+This will not work out of the box with `iki-git-shell` because the C code garbles the `SSH_ORIG_COMMAND` with `strtok`. The following patch is also necessary to carry the command down below:
+
+<pre>
+diff --git a/iki-git-shell.c b/iki-git-shell.c
+index 70250ad..37639a2 100644
+--- a/iki-git-shell.c
++++ b/iki-git-shell.c
+@@ -74,6 +74,10 @@ int main (int argc, char **argv) {
+                fprintf(stderr, "error: SSH_ORIGINAL_COMMAND not set\n");
+                exit(1);
+        }
++       if (asprintf(&command, command) == -1) {
++               perror("asprintf");
++               exit(1);
++       }
+
+        s=strtok(command, " -"); /* handle "git-" and "git " */
+        if (! s) {
+</pre>
+
+That way the tokenizer operates on a copy of the string instead of garbling the environment directly.
+
+Now, I know that:
+
+ 1. this is clunky
+ 2. it's python (heretic! burn! burn!)
+ 3. there's more comments than code (but I took a while to figure that stuff out, so better to share)
+ 4. it doesn't solve git-annex support in ikiwiki (ie. the objects won't get pushed to the source repo)
+ 5. it's 1h30AM on a friday
+
+But:
+
+ 1. it's a start!
+ 2. it works (ie. it will drop keys, share configs, etc)
+ 3. it should be fairly secure
+
+Your feedback would be greatly appreciated here. At the very least I think the patch on iki-git-shell can't hurt, unless hiding the original git command was deliberate. 
+
+Thanks! -- [[anarcat]]

feature request, really...
diff --git a/doc/todo/git-annex_support.mdwn b/doc/todo/git-annex_support.mdwn
new file mode 100644
index 0000000..70980bf
--- /dev/null
+++ b/doc/todo/git-annex_support.mdwn
@@ -0,0 +1,10 @@
+It would be great to support [git-annex](https://git-annex.branchable.com/) in ikiwiki-hosting. One of the things that would need to change would be the `iki-git-shell` command, which currently doesn't allow `git-annex-shell` to run, which breaks `git-annex`. I tried setting the `annex-shell` variable on the client side to `git annex-shell` to try to workaround the issue, but it still fails with:
+
+<pre>
+fatal: unrecognized command 'git-annex-shell '/home/w-...''
+...
+</pre>
+
+The client then sets the `annex-ignore` variable and ignores that remote. And of course we'd also need [ikiwiki itself to support git-annex](https://ikiwiki.info/todo/git-annex_support/) but that's another story - at least allowing uploads would be a nice start.
+
+The workaround, of course, is to set `git-annex-shell` as the command in the `authorized_keys` file instead of `iki-git-shell`... -- [[anarcat]]

bug report
diff --git a/doc/bugs/stale_git_lockfile_cleanup_on_boot.mdwn b/doc/bugs/stale_git_lockfile_cleanup_on_boot.mdwn
new file mode 100644
index 0000000..061edc9
--- /dev/null
+++ b/doc/bugs/stale_git_lockfile_cleanup_on_boot.mdwn
@@ -0,0 +1,5 @@
+A server crash or unclean shutdown can result in .git/index.lck files
+in sites, which prevent further commits.
+
+At startup, ikiwiki-hosting could find such files and remove. It would
+need to do it before the webserver is started to avoid races. --[[Joey]] 

fix typos, document apache-{ssl,source}.conf.tmpl
diff --git a/doc/design/apacheconfig.mdwn b/doc/design/apacheconfig.mdwn
index ec9bb38..2e71337 100644
--- a/doc/design/apacheconfig.mdwn
+++ b/doc/design/apacheconfig.mdwn
@@ -5,7 +5,7 @@ It can be useful to tweak apache settings for a single site. To allow this,
 use `/etc/ikiwiki-hosting/config/$username/apache.conf.tmpl`
 
 This is an apache2 config fragment, that, if present, is inserted into the
-site's generated apache config file by `ikisite enable`. Remeber to run
+site's generated apache config file by `ikisite enable`. Remember to run
 `ikisite enable` if modifying it.
 
 It is inserted inside the `<VirtualHost>` tag in the apache config file,
@@ -34,7 +34,7 @@ for a given site, this file can be used to enable it.
 
 ---
 
-To enable SSL, just install the ssl cerificate to
+To enable SSL, just install the ssl certificate to
 `/etc/ikiwiki-hosting/config/$username/ssl.crt`
 and the key to 
 `/etc/ikiwiki-hosting/config/$username/ssl.key`.
@@ -49,3 +49,14 @@ if the CA need to provide additional certificate chain material.
 Note that it's up to you to configure apache to use SNI if using SSL
 for multiple virtual hosts on a single IP. See
 <http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI>
+
+If you want some Apache configuration to be applied to the SSL version
+of the site but not the normal version (enabling HTTP authentication
+for [[!iki plugins/httpauth desc="the httpauth plugin"]], perhaps),
+put it in `/etc/ikiwiki-hosting/config/$username/apache-ssl.conf.tmpl`.
+
+---
+
+Special configuration for the `source.$hostname.$domain` (gitweb)
+virtual host can be provided too, in
+`/etc/ikiwiki-hosting/config/$username/apache-source.conf.tmpl`.

Improved method of disabling mod_userdir. (smcv)
diff --git a/debian/changelog b/debian/changelog
index a10b890..077fdea 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -20,6 +20,7 @@ ikiwiki-hosting (0.20140228) UNRELEASED; urgency=medium
   * Deal with apache 2.4 upgrade, including making sites-available files
     with the .conf extension. Remains compatable with apache 2.2.
     (smcv) Closes: #744789
+  * Improved method of disabling mod_userdir. (smcv)
 
  -- Joey Hess <joeyh@debian.org>  Fri, 07 Mar 2014 11:38:41 -0400
 
diff --git a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
index fb47c62..ce713c0 100644
--- a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
+++ b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
@@ -25,3 +25,5 @@ My `ready/userdir` [[branch|patch]] fixes that.
 >>   vhosts; new installations won't need to load it at all.
 >>
 >> --[[smcv]]
+
+>>> [[merged|done]] --[[Joey]]

Deal with apache 2.4 upgrade, including making sites-available files with the .conf extension. Remains compatable with apache 2.2. (smcv) Closes: #744789
diff --git a/debian/changelog b/debian/changelog
index 17b58cb..a10b890 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -17,6 +17,9 @@ ikiwiki-hosting (0.20140228) UNRELEASED; urgency=medium
     - Previously, when ssl was enabled, alias urls always redirected
       to the http site. Now, this is only done when 
       redirect_to_https is set.
+  * Deal with apache 2.4 upgrade, including making sites-available files
+    with the .conf extension. Remains compatable with apache 2.2.
+    (smcv) Closes: #744789
 
  -- Joey Hess <joeyh@debian.org>  Fri, 07 Mar 2014 11:38:41 -0400
 
diff --git a/doc/todo/apache_2.4_support.mdwn b/doc/todo/apache_2.4_support.mdwn
index 2166f61..63e7e8f 100644
--- a/doc/todo/apache_2.4_support.mdwn
+++ b/doc/todo/apache_2.4_support.mdwn
@@ -74,3 +74,6 @@ i have a (so far) working [[patch]] in my git repo (`git://src.anarc.at/ikiwiki-
 >>>
 >>> that process could get broken by having both ikisite-example.com and
 >>> ikisite-example.com.conf in sites-available. --s
+
+>>>> Ok, this seems acceptable and I'm ok with punting handling upgrades to
+>>>> 2.4 yet, in hopes apache will deal with it. [[merged|done]] --[[Joey]] 

perhaps I misunderstood the objection?
diff --git a/doc/todo/apache_2.4_support.mdwn b/doc/todo/apache_2.4_support.mdwn
index 0fb3b70..2166f61 100644
--- a/doc/todo/apache_2.4_support.mdwn
+++ b/doc/todo/apache_2.4_support.mdwn
@@ -40,11 +40,28 @@ i have a (so far) working [[patch]] in my git repo (`git://src.anarc.at/ikiwiki-
 >> configured with `$apache_site`? This patch seems to cause them to break
 >> in some way or another until I disable/reenable them all.
 >>
->>> Hmm, it worked for me... I'm still using Apache 2.2 on the server
+>>> I might have misunderstood what you're getting at here: do you mean
+>>> "I have an Apache 2.2 host and switch it to smcv's patched
+>>> ikiwiki-hosting while keeping Apache 2.2", or "I have an Apache 2.2
+>>> host and switch it to Apache 2.4"?
+>>>
+>>> The former worked for me... I'm still using Apache 2.2 on the server
 >>> that I'm interested in upgrading. Old sites remain in the old,
 >>> Apache-2.2-only scheme; when I disable and re-enable a site,
 >>> it's moved to the new scheme, which works either way.
->>> Did you try it and see something go wrong? If so, what? --s
+>>> If you've tried this and encountered a bug, or spotted a bug
+>>> via code review, please explain?
+>>>
+>>> The latter is not (yet) expected to work, unless you disable and
+>>> re-enable all ikisites (which I wanted to avoid for now, because
+>>> I think some of mine still have local edits, although merging my
+>>> ssl branch hopefully removed the need for that). It looks as though
+>>> the Apache 2.4 maintainer scripts might do it, one day. It would
+>>> maybe be reasonable to add an "ikisite migrate" subcommand,
+>>> which either does the disable/enable for every site or does a
+>>> more minimal rename-the-configurations step, and make
+>>> ikiwiki-hosting-web's maintainer script run it - would you like me to
+>>> try that? --s
 >>
 >> Did you consider just making ikisite write out both `$apache_site` and 
 >> `apache_site.conf`? Then the runtime complication of needing to 

still works with 2.2 for me?
diff --git a/doc/todo/apache_2.4_support.mdwn b/doc/todo/apache_2.4_support.mdwn
index aba386f..0fb3b70 100644
--- a/doc/todo/apache_2.4_support.mdwn
+++ b/doc/todo/apache_2.4_support.mdwn
@@ -40,6 +40,20 @@ i have a (so far) working [[patch]] in my git repo (`git://src.anarc.at/ikiwiki-
 >> configured with `$apache_site`? This patch seems to cause them to break
 >> in some way or another until I disable/reenable them all.
 >>
+>>> Hmm, it worked for me... I'm still using Apache 2.2 on the server
+>>> that I'm interested in upgrading. Old sites remain in the old,
+>>> Apache-2.2-only scheme; when I disable and re-enable a site,
+>>> it's moved to the new scheme, which works either way.
+>>> Did you try it and see something go wrong? If so, what? --s
+>>
 >> Did you consider just making ikisite write out both `$apache_site` and 
 >> `apache_site.conf`? Then the runtime complication of needing to 
 >> `a2ensite $apache_site.conf` on 2.2 goes away. --[[Joey]]
+
+>>> Maybe. I was worried that when the Apache maintainers get round to this:
+>>>
+>>>     #XXX: Deal with the sites-available/sites-enabled *.conf transition, e.g. rename
+>>>     #     all files which look like site configuration?
+>>>
+>>> that process could get broken by having both ikisite-example.com and
+>>> ikisite-example.com.conf in sites-available. --s

already fine, I think?
diff --git a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
index 5e6e5b0..fb47c62 100644
--- a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
+++ b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
@@ -12,3 +12,16 @@ My `ready/userdir` [[branch|patch]] fixes that.
 > Anyway, I think that the idea here was to make the confuration work even
 > if used alongside an apache that did have userdir configured for other
 > sites. --[[Joey]]
+
+>> Look at the patch, I think I already addressed both objections :-)
+>>
+>> There are two changes:
+>>
+>> * don't force mod_userdir on in the postinst; upgrades unaffected.
+>> * wrap the `UserDir disabled` directive in `<IfModule mod_userdir.c>`,
+>>   so that if it's loaded, we disable it, but if it isn't, we do nothing.
+>>   Upgraded machines (and machines where the sysadmin wants userdirs on
+>>   another vhost) will load mod_userdir, but disable it for ikisite-managed
+>>   vhosts; new installations won't need to load it at all.
+>>
+>> --[[smcv]]

Several changes to SSL handling (smcv)
* Several changes to SSL handling (smcv)
- Add per-site SSL and source configuration files,
apache-ssl.conf.tmpl and apache-source.conf.tmpl in addition
to the already used apache.conf.tmpl.
- ikiwikihosting ikiwiki plugin now has a redirect_to_https
setting, so users can choose whether their site should force users
to access it via https.
- Previously, when ssl was enabled, alias urls always redirected
to the http site. Now, this is only done when
redirect_to_https is set.
diff --git a/debian/changelog b/debian/changelog
index e8c3f9c..17b58cb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -7,6 +7,16 @@ ikiwiki-hosting (0.20140228) UNRELEASED; urgency=medium
     domain is configured. (smcv)
   * Fix failures when run in a directory others cannot read (such as a
     protected /root). (anarcat, smcv)
+  * Several changes to SSL handling (smcv)
+    - Add per-site SSL and source configuration files,
+      apache-ssl.conf.tmpl and apache-source.conf.tmpl in addition
+      to the already used apache.conf.tmpl.
+    - ikiwikihosting ikiwiki plugin now has a redirect_to_https
+      setting, so users can choose whether their site should force users
+      to access it via https.
+    - Previously, when ssl was enabled, alias urls always redirected
+      to the http site. Now, this is only done when 
+      redirect_to_https is set.
 
  -- Joey Hess <joeyh@debian.org>  Fri, 07 Mar 2014 11:38:41 -0400
 
diff --git a/doc/todo/some_SSL_improvements.mdwn b/doc/todo/some_SSL_improvements.mdwn
index e382da4..52ded46 100644
--- a/doc/todo/some_SSL_improvements.mdwn
+++ b/doc/todo/some_SSL_improvements.mdwn
@@ -41,3 +41,5 @@ example.com, aka example.branchable.com.
     https://e.b.c  |https://www  |https://www  |https://www
 
 --[[smcv]]
+
+> [[merged|done]] --[[Joey]]

comment
diff --git a/doc/todo/apache_2.4_support.mdwn b/doc/todo/apache_2.4_support.mdwn
index 483cb9b..aba386f 100644
--- a/doc/todo/apache_2.4_support.mdwn
+++ b/doc/todo/apache_2.4_support.mdwn
@@ -35,3 +35,11 @@ i have a (so far) working [[patch]] in my git repo (`git://src.anarc.at/ikiwiki-
 > automatic migration in its maintainer scripts before jessie is released
 > (which seems to be the plan). However, it does work with both 2.2 and 2.4.
 > --[[smcv]]
+
+>> What if I have an apache 2.2 host that has lots of existing sites 
+>> configured with `$apache_site`? This patch seems to cause them to break
+>> in some way or another until I disable/reenable them all.
+>>
+>> Did you consider just making ikisite write out both `$apache_site` and 
+>> `apache_site.conf`? Then the runtime complication of needing to 
+>> `a2ensite $apache_site.conf` on 2.2 goes away. --[[Joey]]

comment
diff --git a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
index bfcf60c..5e6e5b0 100644
--- a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
+++ b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
@@ -6,3 +6,9 @@ My `ready/userdir` [[branch|patch]] fixes that.
 <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/commitdiff/refs/heads/ready/userdir>
 
 --[[smcv]]
+
+> What about upgrades?
+> 
+> Anyway, I think that the idea here was to make the confuration work even
+> if used alongside an apache that did have userdir configured for other
+> sites. --[[Joey]]

Fix failures when run in a directory others cannot read (such as a protected /root). (anarcat, smcv)
diff --git a/debian/changelog b/debian/changelog
index a1fb711..e8c3f9c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,8 @@ ikiwiki-hosting (0.20140228) UNRELEASED; urgency=medium
     subscriptions.
   * Fix bug causing it to sometimes wrong username prefix if only one
     domain is configured. (smcv)
+  * Fix failures when run in a directory others cannot read (such as a
+    protected /root). (anarcat, smcv)
 
  -- Joey Hess <joeyh@debian.org>  Fri, 07 Mar 2014 11:38:41 -0400
 
diff --git a/doc/bugs/wiki_creation_impossible.mdwn b/doc/bugs/wiki_creation_impossible.mdwn
index 75f96e0..1b4b7dd 100644
--- a/doc/bugs/wiki_creation_impossible.mdwn
+++ b/doc/bugs/wiki_creation_impossible.mdwn
@@ -25,3 +25,5 @@ error: git failed
 > > > Try my `ready/home` branch, which includes anarcat's, instead?
 > > > <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/shortlog/refs/heads/ready/home>
 > > > --[[smcv]]
+
+[[merged|done]] --[[Joey]]

Fix bug causing it to sometimes wrong username prefix if only one domain is configured. (smcv)
diff --git a/debian/changelog b/debian/changelog
index 303cde2..a1fb711 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,8 @@ ikiwiki-hosting (0.20140228) UNRELEASED; urgency=medium
   * When branching a site, do not copy over the database 
     files including the session database and the list of email
     subscriptions.
+  * Fix bug causing it to sometimes wrong username prefix if only one
+    domain is configured. (smcv)
 
  -- Joey Hess <joeyh@debian.org>  Fri, 07 Mar 2014 11:38:41 -0400
 
diff --git a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
index c204a67..5dc1038 100644
--- a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
+++ b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
@@ -34,3 +34,5 @@ Fixed in my `ready/prefix` [[branch|patch]]:
 <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/shortlog/refs/heads/ready/prefix>
 
 --[[smcv]]
+
+> [[fixed|done]] --[[Joey]]

some patch notes
diff --git a/doc/todo/apache_2.4_support.mdwn b/doc/todo/apache_2.4_support.mdwn
index a5559e5..483cb9b 100644
--- a/doc/todo/apache_2.4_support.mdwn
+++ b/doc/todo/apache_2.4_support.mdwn
@@ -28,4 +28,10 @@ i have a (so far) working [[patch]] in my git repo (`git://src.anarc.at/ikiwiki-
 >
 > Please consider my `ready/apache24` branch.
 > <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/shortlog/refs/heads/ready/apache24>
+>
+> It does not handle migration from ikisite-example.com to
+> ikisite-example.com.conf at the time you install Apache 2.4: that can be done
+> by disabling and re-enabling all sites, if Apache 2.4 doesn't get an
+> automatic migration in its maintainer scripts before jessie is released
+> (which seems to be the plan). However, it does work with both 2.2 and 2.4.
 > --[[smcv]]

tag
diff --git a/doc/todo/some_SSL_improvements.mdwn b/doc/todo/some_SSL_improvements.mdwn
index 1510719..e382da4 100644
--- a/doc/todo/some_SSL_improvements.mdwn
+++ b/doc/todo/some_SSL_improvements.mdwn
@@ -1,4 +1,4 @@
-Please consider my `ready/ssl` branch:
+Please consider my `ready/ssl` [[branch|patch]]:
 <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/shortlog/refs/heads/ready/ssl>
 
 Changes are:

diff --git a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
index 46691d6..c204a67 100644
--- a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
+++ b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
@@ -30,7 +30,7 @@ arbitrarily between the two.
 
 The solution is simple: `next unless $key =~ m/^prefix_/;`
 
-Fixed in my `ready/prefix` branch:
+Fixed in my `ready/prefix` [[branch|patch]]:
 <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/shortlog/refs/heads/ready/prefix>
 
 --[[smcv]]

tag
diff --git a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
index c737cdb..bfcf60c 100644
--- a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
+++ b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
@@ -1,7 +1,7 @@
 ikiwiki-hosting-web.postinst does `a2enmod userdir` so that it can use
 `UserDir disabled`. This seems a little silly.
 
-My `ready/userdir` branch fixes that.
+My `ready/userdir` [[branch|patch]] fixes that.
 
 <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/commitdiff/refs/heads/ready/userdir>
 

new patchset
diff --git a/doc/todo/some_SSL_improvements.mdwn b/doc/todo/some_SSL_improvements.mdwn
new file mode 100644
index 0000000..1510719
--- /dev/null
+++ b/doc/todo/some_SSL_improvements.mdwn
@@ -0,0 +1,43 @@
+Please consider my `ready/ssl` branch:
+<http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/shortlog/refs/heads/ready/ssl>
+
+Changes are:
+
+* Include /etc/ikiwiki-hosting/b-foo/apache-ssl.conf.tmpl in the SSL
+  vhost, but not the unencrypted vhost. This is a good place to configure
+  HTTP basic/digest authentication or adjust SSL ciphers, for instance.
+
+* Similarly, for completeness, include
+  /etc/ikiwiki-hosting/b-foo/apache-source.conf.tmpl in the
+  source.foo vhost.
+
+* apache.conf.tmpl is included in all vhosts (unencrypted, SSL and source)
+  as before.
+
+* Give sites a boolean redirect_to_https option. If on, the normal port-80
+  vhost behaves like the aliases, redirecting to the SSL vhost.
+
+* If a SSL key exists, but redirect_to_https is not set, unencrypted aliases
+  redirect to the unencrypted main site (but SSL aliases redirect to the
+  SSL site).
+
+That last change makes it much more palatable to have a public,
+mostly-read-only site that doesn't need SSL for normal use, but install a
+self-signed or otherwise non-cartel-approved certificate so that a few
+authorized editors (who can be taught to verify the self-signed cert by
+fingerprint) can use password authentication securely. For instance,
+that's probably what I'm going to do for my blog.
+
+Truth table: suppose www.example.com is the canonical/preferred name of
+example.com, aka example.branchable.com.
+
+    redirect from  |r_t_https=0  |r_t_https=1  | old behaviour
+    ---------------+-------------+-------------+-------------
+    http://www.e.c |(no redirect)|https://www  |(no redirect)
+    https://www.e.c|(no redirect)|(no redirect)|(no redirect)
+    http://e.c     |http://www   |https://www  |https://www
+    https://e.c    |https://www  |https://www  |https://www
+    http://e.b.c   |http://www   |https://www  |https://www
+    https://e.b.c  |https://www  |https://www  |https://www
+
+--[[smcv]]

+ more complete patch
diff --git a/doc/bugs/wiki_creation_impossible.mdwn b/doc/bugs/wiki_creation_impossible.mdwn
index 36857e1..75f96e0 100644
--- a/doc/bugs/wiki_creation_impossible.mdwn
+++ b/doc/bugs/wiki_creation_impossible.mdwn
@@ -20,3 +20,8 @@ error: git failed
 > So this should be fairly simple to fix: just change the directory first. It's is probably safe to `chdir($HOME)` anyways... --[[anarcat]]
 >
 > > I did exactly that so [[patch]] in the `dev/usercreate_fails` branch of git repo (`git://src.anarc.at/ikiwiki-hosting`). --[[anarcat]]
+
+> > > This looks good, but incomplete: calling `ikiwiki -setup` also fails.
+> > > Try my `ready/home` branch, which includes anarcat's, instead?
+> > > <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/shortlog/refs/heads/ready/home>
+> > > --[[smcv]]

+patch
diff --git a/doc/todo/apache_2.4_support.mdwn b/doc/todo/apache_2.4_support.mdwn
index 449955c..a5559e5 100644
--- a/doc/todo/apache_2.4_support.mdwn
+++ b/doc/todo/apache_2.4_support.mdwn
@@ -25,3 +25,7 @@ i have a (so far) working [[patch]] in my git repo (`git://src.anarc.at/ikiwiki-
 >
 > I've opened an equivalent bug in Debian so it can be on the
 > Debian Apache packagers' radar. --[[smcv]]
+>
+> Please consider my `ready/apache24` branch.
+> <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/shortlog/refs/heads/ready/apache24>
+> --[[smcv]]

diff --git a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
index 2980e7e..46691d6 100644
--- a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
+++ b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
@@ -31,6 +31,6 @@ arbitrarily between the two.
 The solution is simple: `next unless $key =~ m/^prefix_/;`
 
 Fixed in my `ready/prefix` branch:
-<http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/commitdiff/refs/heads/ready/prefix>
+<http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/shortlog/refs/heads/ready/prefix>
 
 --[[smcv]]

+patch
diff --git a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
index 948a8e6..2980e7e 100644
--- a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
+++ b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
@@ -29,3 +29,8 @@ creating both `ih-foo` and `domains-foo`, and distributing its files
 arbitrarily between the two.
 
 The solution is simple: `next unless $key =~ m/^prefix_/;`
+
+Fixed in my `ready/prefix` branch:
+<http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/commitdiff/refs/heads/ready/prefix>
+
+--[[smcv]]

sign page
diff --git a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
index d76b2c6..c737cdb 100644
--- a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
+++ b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
@@ -4,3 +4,5 @@ ikiwiki-hosting-web.postinst does `a2enmod userdir` so that it can use
 My `ready/userdir` branch fixes that.
 
 <http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/commitdiff/refs/heads/ready/userdir>
+
+--[[smcv]]

no format directive here apparently
diff --git a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
index b90a44c..948a8e6 100644
--- a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
+++ b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
@@ -9,7 +9,6 @@ Suppose you have this:
 
 In `username()` we do this:
 
-[[!format perl """
 	# add unique prefix to avoid collisions with system users and 
 	# other top domains
 	my $prefix;
@@ -20,7 +19,6 @@ In `username()` we do this:
 		$prefix=~s/^prefix_//;
 		last;
 	}
-"""
 
 The value of `domains` is defined and equals `example.com`, so if it happens
 to come first in the hash (randomized order), ikisite will set

new bug report
diff --git a/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
new file mode 100644
index 0000000..b90a44c
--- /dev/null
+++ b/doc/bugs/picks_wrong_username_prefix_if_only_one_domain_supported.mdwn
@@ -0,0 +1,33 @@
+Suppose you have this:
+
+    # List supported domains here.
+    domains=example.com
+    
+    # Username prefixes used to ensure unique usernames are used for
+    # sites under different top level domains. Keep the prefixes short!
+    prefix_ih=example.com
+
+In `username()` we do this:
+
+[[!format perl """
+	# add unique prefix to avoid collisions with system users and 
+	# other top domains
+	my $prefix;
+	foreach my $key (keys %config) {
+		next unless defined $config{$key};
+		next unless $config{$key} eq $topdomain;
+		$prefix=$key;
+		$prefix=~s/^prefix_//;
+		last;
+	}
+"""
+
+The value of `domains` is defined and equals `example.com`, so if it happens
+to come first in the hash (randomized order), ikisite will set
+`$prefix=domains`, leading to usernames like `domains-foo` instead of the
+intended `ih-foo`. At least in unstable, this happens inconsistently
+(again, randomized hash order) so I ended up with `foo.example.com`
+creating both `ih-foo` and `domains-foo`, and distributing its files
+arbitrarily between the two.
+
+The solution is simple: `next unless $key =~ m/^prefix_/;`

easy trivial improvement
diff --git a/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
new file mode 100644
index 0000000..d76b2c6
--- /dev/null
+++ b/doc/todo/do_not_enable_mod__95__userdir_just_so_we_can_disable_it.mdwn
@@ -0,0 +1,6 @@
+ikiwiki-hosting-web.postinst does `a2enmod userdir` so that it can use
+`UserDir disabled`. This seems a little silly.
+
+My `ready/userdir` branch fixes that.
+
+<http://git.pseudorandom.co.uk/smcv/ikiwiki-hosting.git/commitdiff/refs/heads/ready/userdir>

comments
diff --git a/doc/todo/apache_2.4_support.mdwn b/doc/todo/apache_2.4_support.mdwn
index 2a59287..449955c 100644
--- a/doc/todo/apache_2.4_support.mdwn
+++ b/doc/todo/apache_2.4_support.mdwn
@@ -1,3 +1,27 @@
 apache 2.4 has some changes in Debian which makes ikiwiki-hosting struggle. at the very least the filenames in `sites-available` need to change to have a `.conf` suffix, but there may be more I'm missing.
 
 i have a (so far) working [[patch]] in my git repo (`git://src.anarc.at/ikiwiki-hosting`) branch `dev/apache24`. --[[anarcat]]
+
+> I think your patch is going to break Apache 2.2 users (like, er,
+> branchable.com) - I think it's OK to write out `$apache_site.conf`
+> unconditionally, but then you have to use `a2ensite $apache_site.conf`
+> for 2.2 or `a2ensite $apache_site` for 2.4.
+>
+> It would also be nice to clean up the old files automatically.
+>
+> Lower-priority, it would be nice to avoid the deprecated (and somewhat
+> confusing) Order, Allow and Deny directives for 2.4, which could be
+> achieved like so:
+>
+>     <IfVersion < 2.4>
+>     Order allow,deny
+>     allow from all
+>     </IfVersion>
+>     <IfVersion >= 2.4>
+>     Require all granted
+>     </IfVersion>
+>
+> or by using the template engine.
+>
+> I've opened an equivalent bug in Debian so it can be on the
+> Debian Apache packagers' radar. --[[smcv]]

comment
diff --git a/doc/bugs/too_much_garbage_to_remove_when_failing_to_create.mdwn b/doc/bugs/too_much_garbage_to_remove_when_failing_to_create.mdwn
index 2e6a44a..9a37847 100644
--- a/doc/bugs/too_much_garbage_to_remove_when_failing_to_create.mdwn
+++ b/doc/bugs/too_much_garbage_to_remove_when_failing_to_create.mdwn
@@ -15,3 +15,6 @@ i have a crazy [[patch]] to workaround that... it seems that eval doesn't unroll
 using this i can reliably delete any traces of any site, at least enough to fool `branch` again.
 
 this is in the `dev/idempotent-delete` branch of my git repo (`git://src.anarc.at/ikiwiki-hosting`). --[[anarcat]]
+
+> I use `ikisite userdelete` in these situations, but it can leave cruft
+> behind.. --[[Joey]]

yet another patch
diff --git a/doc/todo/apache_2.4_support.mdwn b/doc/todo/apache_2.4_support.mdwn
new file mode 100644
index 0000000..2a59287
--- /dev/null
+++ b/doc/todo/apache_2.4_support.mdwn
@@ -0,0 +1,3 @@
+apache 2.4 has some changes in Debian which makes ikiwiki-hosting struggle. at the very least the filenames in `sites-available` need to change to have a `.conf` suffix, but there may be more I'm missing.
+
+i have a (so far) working [[patch]] in my git repo (`git://src.anarc.at/ikiwiki-hosting`) branch `dev/apache24`. --[[anarcat]]