Tim Clifford: 1 Add virtual host support 3 files changed, 93 insertions(+), 22 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~cadence/bliz-devel/patches/30977/mbox | git am -3Learn more about email & git
--- I originally wanted to deal with certificates via SNI, but it seemed pretty unworkable without quite a lot more complexity and dependencies. This patch instead adds some stuff to certs.fish to make it easy to add new domains to the existing certificate (without breaking TOFU) certs.fish | 84 ++++++++++++++++++++++++++++++++++++++----------- src/cgi.fish | 24 ++++++++++++-- src/config.fish | 7 +++-- 3 files changed, 93 insertions(+), 22 deletions(-) diff --git a/certs.fish b/certs.fish index 87c09d1..4790240 100755 --- a/certs.fish +++ b/certs.fish @@ -1,28 +1,76 @@ #!/usr/bin/env fish +# -a or --add to add domains instead of generating a new certificate +argparse 'a/add=+' -- $argv + cd (dirname (status current-filename))/certs; or exit set days 10000 # 27 years -if test -f key.pem - echo 'Warning! If you have already generated keys, they will be overwritten.' - echo 'If you continue, you will fail Trust On First Use, and some browsers may' - echo 'be unhappy with your site.' - echo 'If you have not yet published your site, you can ignore this warning.' +if ! test "$_flag_add" + if test -f key.pem + echo 'Warning! If you have already generated keys, they will be overwritten.' + echo 'If you continue, you will fail Trust On First Use, and some browsers may' + echo 'be unhappy with your site.' + echo 'If you have not yet published your site, you can ignore this warning.' + echo + end + + echo 'To generate certificatates, enter the domain name that your site will be' + echo 'eventually published on. If you don\'t care, you can enter nothing.' + echo -n 'Example input: '; set_color cyan; echo 'an-excellent.website' + read domain -P 'domain name > ' echo -end -echo 'To generate certificatates, enter the domain name that your site will be' -echo 'eventually published on. If you don\'t care, you can enter nothing.' -echo -n 'Example input: '; set_color cyan; echo 'an-excellent.website' -read domain -P 'domain name > ' -echo + # Country, state, locality, organisation, unit, domain name, email + echo -en ".\n.\n.\n.\n.\n$domain\n.\n" | \ + openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days $days -nodes \ + ; or exit + + echo + echo + echo 'Everything appears to be okay.' +else + # check a key actually exists + + if ! test -f "key.pem" + echo "You need to create a key before you can add domains to it!" + exit 1 + end + + # Get any existing Common Name + set cn (openssl x509 -noout -subject -in cert.pem | string match -r 'CN *= *([^ ,]*)')[2] + + # Get any existing Subject Alternative Name(s) + set san (openssl x509 -in cert.pem -noout -ext subjectAltName | grep -v '^X509' | string trim) -# Country, state, locality, organisation, unit, domain name, email -echo -en ".\n.\n.\n.\n.\n$domain\n.\n" | \ - openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days $days -nodes \ - ; or exit + # add new domains + for dom in $_flag_add + if test $san + set san "$san, DNS:$dom" + else + set san "DNS:$dom" + end + end -echo -echo -echo 'Everything appears to be okay.' + # some clients (at least amfora) don't seem to like certs that use both CN and SAN, + # so make sure the CN is in both of them + if ! string match -rq "DNS:$cn"'($|,)' -- $san + set san "DNS:$cn, $san" + end + + echo "This key will now be valid for: '$san'" + read -P "Ok? (y/N) " yn + + if string match -r '^[Yy]' -- $yn + openssl req -x509 -key key.pem -config \ + (begin; \ + cat /etc/ssl/openssl.cnf; \ + echo "[ subject_alt_name ]"; \ + echo "subjectAltName = $san"; \ + end | psub) \ + -extensions subject_alt_name \ + -subj "/CN=$cn" \ + -out cert.pem + end +end diff --git a/src/cgi.fish b/src/cgi.fish index 1f66a18..d06d4fc 100644 --- a/src/cgi.fish +++ b/src/cgi.fish @@ -45,8 +45,28 @@ if test $req_query = "source=1" set source_mode true end -# future host handling code here? -# ... +server_echo $req_host +# host handling +set serve_root (string match -r -- '^'$req_host':(.*)' $serve_roots)[2] + +# if the host is not explicitly configured, use the default +if test -z $serve_root + set serve_root (string match -r -- '^default:(.*)' $serve_roots)[2] +end + +server_echo $serve_root + +# if it's still empty, fail +if test -z $serve_root + gem_header 59 "Bliz server: no server root configured for $req_host" + exit +end + +# if the path doesn't exist, fail +if ! test -d $serve_root + gem_header 59 "Bliz server: configured server root does not exist on host" + exit +end # normalise path to remove /./, some broken clients add it # `x` is added to the start and end of the string so that leading and trailing slashes won't be removed diff --git a/src/config.fish b/src/config.fish index 8e6c474..cd690d6 100644 --- a/src/config.fish +++ b/src/config.fish @@ -19,13 +19,16 @@ set spartan_port # Optional - remove this value to not serve data. set mercury_port 1964 -set serve_root serve +set serve_roots "default:serve" # add vhosts in the form "example1.com:/path/to/root" "example2.com:/another/root" etc set serve_index # add arguments here for default index preference set debug_server_echo false source personal/config.fish + # Normalise -set serve_root (string trim -r -c / -- $serve_root) +for i in (seq (count serve_roots)) + set serve_roots[$i] (string trim -r -c / -- $serve_roots[$i]) +end -- 2.35.1