1.1--- a/bootstrap.sh Mon May 27 23:09:57 2024 +0000
1.2+++ b/bootstrap.sh Tue May 28 01:40:54 2024 +0000
1.3@@ -1,1 +1,352 @@
1.4-#!/usr/bin/env sh
1.5+#!/bin/sh
1.6+set -eu
1.7+main() {
1.8+ . ./check.sh
1.9+ download --check
1.10+ local _arch=$(_read arch | tr -d '"')
1.11+ local _ext=""
1.12+ case "$_arch" in
1.13+ *windows*)
1.14+ _ext=".exe"
1.15+ ;;
1.16+ esac
1.17+ local _url="https://packy.compiler.company/dist/${_arch}"
1.18+ local _stash
1.19+ if ! _stash=".stash"; then
1.20+ # Because the previous command ran in a subshell, we must manually
1.21+ # propagate exit status.
1.22+ exit 1
1.23+ fi
1.24+ ensure mkdir -p "${_stash}/src"
1.25+ ensure mkdir -p "${_stash}/bin"
1.26+ local _sk_url="${_url}/bin/sk"
1.27+ local _sbcl_url="${_url}/pack/sbcl.tar.zst"
1.28+ local _rocksdb_url="${_url}/pack/rocksdb.tar.zst"
1.29+ ensure download "$_sbcl_url" "${_stash}/src/sbcl.tar.zst" "$_arch"
1.30+ ensure download "$_rocksdb_url" "${_stash}/src/rocksdb.tar.zst" "$_arch"
1.31+ ensure download "$_sk_url" "${_stash}/bin/sk" "$_arch"
1.32+}
1.33+
1.34+_read() {
1.35+ grep ":$1" $INFRA_HOST_CONFIG | cut -d' ' -f 2-
1.36+}
1.37+
1.38+say() {
1.39+ printf 'bootstrap.sh: %s\n' "$1"
1.40+}
1.41+
1.42+err() {
1.43+ say "$1" >&2
1.44+ exit 1
1.45+}
1.46+
1.47+check_cmd() {
1.48+ command -v "$1" > /dev/null 2>&1
1.49+}
1.50+
1.51+need_cmd() {
1.52+ if ! check_cmd "$1"; then
1.53+ err "need '$1' (command not found)"
1.54+ fi
1.55+}
1.56+
1.57+# Run a command that should never fail. If the command fails execution
1.58+# will immediately terminate with an error showing the failing
1.59+# command.
1.60+ensure() {
1.61+ if ! "$@"; then err "command failed: $*"; fi
1.62+}
1.63+
1.64+# Check if curl supports the --retry flag, then pass it to the curl invocation.
1.65+check_curl_for_retry_support() {
1.66+ local _retry_supported=""
1.67+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
1.68+ if check_help_for "notspecified" "curl" "--retry"; then
1.69+ _retry_supported="--retry 3"
1.70+ if check_help_for "notspecified" "curl" "--continue-at"; then
1.71+ # "-C -" tells curl to automatically find where to resume the download when retrying.
1.72+ _retry_supported="--retry 3 -C -"
1.73+ fi
1.74+ fi
1.75+
1.76+ RETVAL="$_retry_supported"
1.77+}
1.78+
1.79+# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
1.80+# if support by local tools is detected. Detection currently supports these curl backends:
1.81+# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
1.82+get_ciphersuites_for_curl() {
1.83+ if [ -n "${TLS_CIPHERSUITES-}" ]; then
1.84+ # user specified custom cipher suites, assume they know what they're doing
1.85+ RETVAL="$TLS_CIPHERSUITES"
1.86+ return
1.87+ fi
1.88+
1.89+ local _openssl_syntax="no"
1.90+ local _gnutls_syntax="no"
1.91+ local _backend_supported="yes"
1.92+ if curl -V | grep -q ' OpenSSL/'; then
1.93+ _openssl_syntax="yes"
1.94+ elif curl -V | grep -iq ' LibreSSL/'; then
1.95+ _openssl_syntax="yes"
1.96+ elif curl -V | grep -iq ' BoringSSL/'; then
1.97+ _openssl_syntax="yes"
1.98+ elif curl -V | grep -iq ' GnuTLS/'; then
1.99+ _gnutls_syntax="yes"
1.100+ else
1.101+ _backend_supported="no"
1.102+ fi
1.103+
1.104+ local _args_supported="no"
1.105+ if [ "$_backend_supported" = "yes" ]; then
1.106+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
1.107+ if check_help_for "notspecified" "curl" "--tlsv1.2" "--ciphers" "--proto"; then
1.108+ _args_supported="yes"
1.109+ fi
1.110+ fi
1.111+
1.112+ local _cs=""
1.113+ if [ "$_args_supported" = "yes" ]; then
1.114+ if [ "$_openssl_syntax" = "yes" ]; then
1.115+ _cs=$(get_strong_ciphersuites_for "openssl")
1.116+ elif [ "$_gnutls_syntax" = "yes" ]; then
1.117+ _cs=$(get_strong_ciphersuites_for "gnutls")
1.118+ fi
1.119+ fi
1.120+
1.121+ RETVAL="$_cs"
1.122+}
1.123+
1.124+# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
1.125+# if support by local tools is detected. Detection currently supports these wget backends:
1.126+# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
1.127+get_ciphersuites_for_wget() {
1.128+ if [ -n "${TLS_CIPHERSUITES-}" ]; then
1.129+ # user specified custom cipher suites, assume they know what they're doing
1.130+ RETVAL="$TLS_CIPHERSUITES"
1.131+ return
1.132+ fi
1.133+
1.134+ local _cs=""
1.135+ if wget -V | grep -q '\-DHAVE_LIBSSL'; then
1.136+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
1.137+ if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
1.138+ _cs=$(get_strong_ciphersuites_for "openssl")
1.139+ fi
1.140+ elif wget -V | grep -q '\-DHAVE_LIBGNUTLS'; then
1.141+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
1.142+ if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
1.143+ _cs=$(get_strong_ciphersuites_for "gnutls")
1.144+ fi
1.145+ fi
1.146+
1.147+ RETVAL="$_cs"
1.148+}
1.149+
1.150+check_help_for() {
1.151+ local _arch
1.152+ local _cmd
1.153+ local _arg
1.154+ _arch="$1"
1.155+ shift
1.156+ _cmd="$1"
1.157+ shift
1.158+
1.159+ local _category
1.160+ if "$_cmd" --help | grep -q 'For all options use the manual or "--help all".'; then
1.161+ _category="all"
1.162+ else
1.163+ _category=""
1.164+ fi
1.165+
1.166+ case "$_arch" in
1.167+
1.168+ *darwin*)
1.169+ if check_cmd sw_vers; then
1.170+ case $(sw_vers -productVersion) in
1.171+ 10.*)
1.172+ # If we're running on macOS, older than 10.13, then we always
1.173+ # fail to find these options to force fallback
1.174+ if [ "$(sw_vers -productVersion | cut -d. -f2)" -lt 13 ]; then
1.175+ # Older than 10.13
1.176+ echo "Warning: Detected macOS platform older than 10.13"
1.177+ return 1
1.178+ fi
1.179+ ;;
1.180+ 11.*)
1.181+ # We assume Big Sur will be OK for now
1.182+ ;;
1.183+ *)
1.184+ # Unknown product version, warn and continue
1.185+ echo "Warning: Detected unknown macOS major version: $(sw_vers -productVersion)"
1.186+ echo "Warning TLS capabilities detection may fail"
1.187+ ;;
1.188+ esac
1.189+ fi
1.190+ ;;
1.191+
1.192+ esac
1.193+
1.194+ for _arg in "$@"; do
1.195+ if ! "$_cmd" --help "$_category" | grep -q -- "$_arg"; then
1.196+ return 1
1.197+ fi
1.198+ done
1.199+
1.200+ true # not strictly needed
1.201+}
1.202+
1.203+# Return strong TLS 1.2-1.3 cipher suites in OpenSSL or GnuTLS syntax. TLS 1.2
1.204+# excludes non-ECDHE and non-AEAD cipher suites. DHE is excluded due to bad
1.205+# DH params often found on servers (see RFC 7919). Sequence matches or is
1.206+# similar to Firefox 68 ESR with weak cipher suites disabled via about:config.
1.207+# $1 must be openssl or gnutls.
1.208+get_strong_ciphersuites_for() {
1.209+ if [ "$1" = "openssl" ]; then
1.210+ # OpenSSL is forgiving of unknown values, no problems with TLS 1.3 values on versions that don't support it yet.
1.211+ echo "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"
1.212+ elif [ "$1" = "gnutls" ]; then
1.213+ # GnuTLS isn't forgiving of unknown values, so this may require a GnuTLS version that supports TLS 1.3 even if wget doesn't.
1.214+ # Begin with SECURE128 (and higher) then remove/add to build cipher suites. Produces same 9 cipher suites as OpenSSL but in slightly different order.
1.215+ echo "SECURE128:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-DTLS-ALL:-CIPHER-ALL:-MAC-ALL:-KX-ALL:+AEAD:+ECDHE-ECDSA:+ECDHE-RSA:+AES-128-GCM:+CHACHA20-POLY1305:+AES-256-GCM"
1.216+ fi
1.217+}
1.218+
1.219+check_proc() {
1.220+ # Check for /proc by looking for the /proc/self/exe link
1.221+ # This is only run on Linux
1.222+ if ! test -L /proc/self/exe ; then
1.223+ err "fatal: Unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc."
1.224+ fi
1.225+}
1.226+
1.227+get_bitness() {
1.228+ need_cmd head
1.229+ # Architecture detection without dependencies beyond coreutils.
1.230+ # ELF files start out "\x7fELF", and the following byte is
1.231+ # 0x01 for 32-bit and
1.232+ # 0x02 for 64-bit.
1.233+ # The printf builtin on some shells like dash only supports octal
1.234+ # escape sequences, so we use those.
1.235+ local _current_exe_head
1.236+ _current_exe_head=$(head -c 5 /proc/self/exe )
1.237+ if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then
1.238+ echo 32
1.239+ elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then
1.240+ echo 64
1.241+ else
1.242+ err "unknown platform bitness"
1.243+ fi
1.244+}
1.245+
1.246+is_host_amd64_elf() {
1.247+ need_cmd head
1.248+ need_cmd tail
1.249+ # ELF e_machine detection without dependencies beyond coreutils.
1.250+ # Two-byte field at offset 0x12 indicates the CPU,
1.251+ # but we're interested in it being 0x3E to indicate amd64, or not that.
1.252+ local _current_exe_machine
1.253+ _current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1)
1.254+ [ "$_current_exe_machine" = "$(printf '\076')" ]
1.255+}
1.256+
1.257+get_endianness() {
1.258+ local cputype=$1
1.259+ local suffix_eb=$2
1.260+ local suffix_el=$3
1.261+
1.262+ # detect endianness without od/hexdump, like get_bitness() does.
1.263+ need_cmd head
1.264+ need_cmd tail
1.265+
1.266+ local _current_exe_endianness
1.267+ _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)"
1.268+ if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then
1.269+ echo "${cputype}${suffix_el}"
1.270+ elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then
1.271+ echo "${cputype}${suffix_eb}"
1.272+ else
1.273+ err "unknown platform endianness"
1.274+ fi
1.275+}
1.276+
1.277+# This wraps curl or wget. Try curl first, if not installed,
1.278+# use wget instead.
1.279+download() {
1.280+ local _dld
1.281+ local _ciphersuites
1.282+ local _err
1.283+ local _status
1.284+ local _retry
1.285+ if check_cmd curl; then
1.286+ _dld=curl
1.287+ elif check_cmd wget; then
1.288+ _dld=wget
1.289+ else
1.290+ _dld='curl or wget' # to be used in error message of need_cmd
1.291+ fi
1.292+
1.293+ if [ "$1" = --check ]; then
1.294+ need_cmd "$_dld"
1.295+ elif [ "$_dld" = curl ]; then
1.296+ check_curl_for_retry_support
1.297+ _retry="$RETVAL"
1.298+ get_ciphersuites_for_curl
1.299+ _ciphersuites="$RETVAL"
1.300+ if [ -n "$_ciphersuites" ]; then
1.301+ _err=$(curl $_retry --proto '=https' --tlsv1.2 --ciphers "$_ciphersuites" --silent --show-error --fail --location "$1" --output "$2" 2>&1)
1.302+ _status=$?
1.303+ else
1.304+ echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
1.305+ if ! check_help_for "$3" curl --proto --tlsv1.2; then
1.306+ echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
1.307+ _err=$(curl $_retry --silent --show-error --fail --location "$1" --output "$2" 2>&1)
1.308+ _status=$?
1.309+ else
1.310+ _err=$(curl $_retry --proto '=https' --tlsv1.2 --silent --show-error --fail --location "$1" --output "$2" 2>&1)
1.311+ _status=$?
1.312+ fi
1.313+ fi
1.314+ if [ -n "$_err" ]; then
1.315+ echo "$_err" >&2
1.316+ if echo "$_err" | grep -q 404$; then
1.317+ err "installer for platform '$3' not found, this may be unsupported"
1.318+ fi
1.319+ fi
1.320+ return $_status
1.321+ elif [ "$_dld" = wget ]; then
1.322+ if [ "$(wget -V 2>&1|head -2|tail -1|cut -f1 -d" ")" = "BusyBox" ]; then
1.323+ echo "Warning: using the BusyBox version of wget. Not enforcing strong cipher suites for TLS or TLS v1.2, this is potentially less secure"
1.324+ _err=$(wget "$1" -O "$2" 2>&1)
1.325+ _status=$?
1.326+ else
1.327+ get_ciphersuites_for_wget
1.328+ _ciphersuites="$RETVAL"
1.329+ if [ -n "$_ciphersuites" ]; then
1.330+ _err=$(wget --https-only --secure-protocol=TLSv1_2 --ciphers "$_ciphersuites" "$1" -O "$2" 2>&1)
1.331+ _status=$?
1.332+ else
1.333+ echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
1.334+ if ! check_help_for "$3" wget --https-only --secure-protocol; then
1.335+ echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
1.336+ _err=$(wget "$1" -O "$2" 2>&1)
1.337+ _status=$?
1.338+ else
1.339+ _err=$(wget --https-only --secure-protocol=TLSv1_2 "$1" -O "$2" 2>&1)
1.340+ _status=$?
1.341+ fi
1.342+ fi
1.343+ fi
1.344+ if [ -n "$_err" ]; then
1.345+ echo "$_err" >&2
1.346+ if echo "$_err" | grep -q ' 404 Not Found$'; then
1.347+ err "installer for platform '$3' not found, this may be unsupported"
1.348+ fi
1.349+ fi
1.350+ return $_status
1.351+ else
1.352+ err "Unknown downloader" # should not reach here
1.353+ fi
1.354+}
1.355+
1.356+main "$@" || exit 1
2.1--- a/check.sh Mon May 27 23:09:57 2024 +0000
2.2+++ b/check.sh Tue May 28 01:40:54 2024 +0000
2.3@@ -16,8 +16,8 @@
2.4 need_cmd awk
2.5 need_cmd head
2.6 need_cmd tail
2.7- host_config_file=$(cat /proc/sys/kernel/hostname).sxp
2.8- rm -f $host_config_file
2.9+ export INFRA_HOST_CONFIG=$(cat /proc/sys/kernel/hostname).sxp
2.10+ rm -f $INFRA_HOST_CONFIG
2.11 check_mem
2.12 local _mem_total="$RETVAL"
2.13 check_disk
2.14@@ -41,7 +41,6 @@
2.15 *)
2.16 _write ":ext nil"
2.17 esac
2.18- print_env
2.19 }
2.20
2.21 say() {
2.22@@ -53,7 +52,7 @@
2.23 }
2.24
2.25 _write() {
2.26- say "$1" >> $host_config_file
2.27+ say "$1" >> $INFRA_HOST_CONFIG
2.28 }
2.29
2.30 err() {
3.1--- a/containers/Containerfile.box Mon May 27 23:09:57 2024 +0000
3.2+++ b/containers/Containerfile.box Tue May 28 01:40:54 2024 +0000
3.3@@ -1,7 +1,5 @@
3.4 FROM localhost/archlinux:latest
3.5 RUN --network=host pacman -Sy uutils-coreutils sysstat iotop imagemagick giflib libgccjit libxaw snappy sbcl liburing libxkbcommon nuklear --noconfirm
3.6-# VOLUME /opt/store
3.7-# VOLUME /opt/stash
3.8 # custom
3.9 ARG DEV=dev
3.10 ARG DEV_HOME=/home/${DEV}
3.11@@ -15,27 +13,22 @@
3.12 ENV CARGO_HOME="/usr/local/share/cargo"
3.13 ENV RUSTUP_HOME="/usr/local/share/rustup"
3.14 # stage1
3.15-RUN sh scripts/get-sk.sh /usr/local/bin
3.16-RUN sk make rustup
3.17+RUN ./bootstrap.sh
3.18 ENV PATH="$PATH:/usr/local/share/cargo/bin"
3.19+RUN .stash/bin/sk make rustup
3.20 RUN rustup update
3.21 # dev rustc components
3.22 RUN rustup default nightly
3.23 RUN rustup component add --toolchain nightly rust-src rust-analyzer rustc-dev llvm-tools-preview
3.24-# RUN sh scripts/install-nushell-pack.sh
3.25-# RUN sh scripts/install-emacs-pack.sh
3.26-# RUN sh scripts/install-sbcl-pack.sh
3.27-# RUN sh scripts/install-rocksdb-pack.sh
3.28-# RUN sh scripts/install-cargo-tools.sh
3.29-RUN sk make sbcl
3.30-RUN sk make quicklisp
3.31-RUN sk make sbcl-install
3.32-RUN sk make tree-sitter
3.33-RUN sk make tree-sitter-langs
3.34-RUN sk make emacs-mini
3.35-RUN sk make emacs-install
3.36-RUN sk make rocksdb
3.37-RUN sk make rocksdb-install
3.38+RUN .stash/bin/sk make sbcl
3.39+RUN .stash/bin/sk make quicklisp
3.40+RUN .stash/bin/sk make sbcl-install
3.41+RUN .stash/bin/sk make tree-sitter
3.42+RUN .stash/bin/sk make tree-sitter-langs
3.43+RUN .stash/bin/sk make emacs-mini
3.44+RUN .stash/bin/sk make emacs-install
3.45+RUN .stash/bin/sk make rocksdb
3.46+RUN .stash/bin/sk make rocksdb-install
3.47 #ADD etc/sbclrc /etc/sbclrc
3.48 #COPY etc/skel/ /etc/skel/
3.49 #ADD etc/shells /etc/
4.1--- a/install.sh Mon May 27 23:09:57 2024 +0000
4.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3@@ -1,566 +0,0 @@
4.4-#!/bin/sh
4.5-set -eu
4.6-main() {
4.7- download --check
4.8-
4.9- get_architecture || return 1
4.10- local _arch="$RETVAL"
4.11- assert_nz "$_arch" "arch"
4.12-
4.13- local _ext=""
4.14- case "$_arch" in
4.15- *windows*)
4.16- _ext=".exe"
4.17- ;;
4.18- esac
4.19-
4.20- local _url="https://packy.compiler.company/dist/${_arch}"
4.21- local _stash
4.22- if ! _stash=".stash"; then
4.23- # Because the previous command ran in a subshell, we must manually
4.24- # propagate exit status.
4.25- exit 1
4.26- fi
4.27- ensure mkdir -p "$_stash"
4.28- local _cc_url="${_url}/cc-install"
4.29- local _sbcl_url="${_url}/pack/sbcl.tar.zst"
4.30- local _rocksdb_url="${_url}/pack/rocksdb.tar.zst"
4.31- ensure download "$_sbcl_url" "${_stash}/sbcl.tar.zst" "$_arch"
4.32- ensure download "$_rocksdb_url" "${_stash}/rocksdb.tar.zst" "$_arch"
4.33- ensure download "$_cc_url" "${_stash}/cc-install" "$_arch"
4.34-}
4.35-
4.36-say() {
4.37- printf 'install.sh: %s\n' "$1"
4.38-}
4.39-
4.40-err() {
4.41- say "$1" >&2
4.42- exit 1
4.43-}
4.44-
4.45-assert_nz() {
4.46- if [ -z "$1" ]; then err "assert_nz $2"; fi
4.47-}
4.48-
4.49-check_cmd() {
4.50- command -v "$1" > /dev/null 2>&1
4.51-}
4.52-
4.53-need_cmd() {
4.54- if ! check_cmd "$1"; then
4.55- err "need '$1' (command not found)"
4.56- fi
4.57-}
4.58-
4.59-# Run a command that should never fail. If the command fails execution
4.60-# will immediately terminate with an error showing the failing
4.61-# command.
4.62-ensure() {
4.63- if ! "$@"; then err "command failed: $*"; fi
4.64-}
4.65-
4.66-# Check if curl supports the --retry flag, then pass it to the curl invocation.
4.67-check_curl_for_retry_support() {
4.68- local _retry_supported=""
4.69- # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
4.70- if check_help_for "notspecified" "curl" "--retry"; then
4.71- _retry_supported="--retry 3"
4.72- if check_help_for "notspecified" "curl" "--continue-at"; then
4.73- # "-C -" tells curl to automatically find where to resume the download when retrying.
4.74- _retry_supported="--retry 3 -C -"
4.75- fi
4.76- fi
4.77-
4.78- RETVAL="$_retry_supported"
4.79-}
4.80-
4.81-# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
4.82-# if support by local tools is detected. Detection currently supports these curl backends:
4.83-# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
4.84-get_ciphersuites_for_curl() {
4.85- if [ -n "${TLS_CIPHERSUITES-}" ]; then
4.86- # user specified custom cipher suites, assume they know what they're doing
4.87- RETVAL="$TLS_CIPHERSUITES"
4.88- return
4.89- fi
4.90-
4.91- local _openssl_syntax="no"
4.92- local _gnutls_syntax="no"
4.93- local _backend_supported="yes"
4.94- if curl -V | grep -q ' OpenSSL/'; then
4.95- _openssl_syntax="yes"
4.96- elif curl -V | grep -iq ' LibreSSL/'; then
4.97- _openssl_syntax="yes"
4.98- elif curl -V | grep -iq ' BoringSSL/'; then
4.99- _openssl_syntax="yes"
4.100- elif curl -V | grep -iq ' GnuTLS/'; then
4.101- _gnutls_syntax="yes"
4.102- else
4.103- _backend_supported="no"
4.104- fi
4.105-
4.106- local _args_supported="no"
4.107- if [ "$_backend_supported" = "yes" ]; then
4.108- # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
4.109- if check_help_for "notspecified" "curl" "--tlsv1.2" "--ciphers" "--proto"; then
4.110- _args_supported="yes"
4.111- fi
4.112- fi
4.113-
4.114- local _cs=""
4.115- if [ "$_args_supported" = "yes" ]; then
4.116- if [ "$_openssl_syntax" = "yes" ]; then
4.117- _cs=$(get_strong_ciphersuites_for "openssl")
4.118- elif [ "$_gnutls_syntax" = "yes" ]; then
4.119- _cs=$(get_strong_ciphersuites_for "gnutls")
4.120- fi
4.121- fi
4.122-
4.123- RETVAL="$_cs"
4.124-}
4.125-
4.126-# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
4.127-# if support by local tools is detected. Detection currently supports these wget backends:
4.128-# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
4.129-get_ciphersuites_for_wget() {
4.130- if [ -n "${TLS_CIPHERSUITES-}" ]; then
4.131- # user specified custom cipher suites, assume they know what they're doing
4.132- RETVAL="$TLS_CIPHERSUITES"
4.133- return
4.134- fi
4.135-
4.136- local _cs=""
4.137- if wget -V | grep -q '\-DHAVE_LIBSSL'; then
4.138- # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
4.139- if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
4.140- _cs=$(get_strong_ciphersuites_for "openssl")
4.141- fi
4.142- elif wget -V | grep -q '\-DHAVE_LIBGNUTLS'; then
4.143- # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
4.144- if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
4.145- _cs=$(get_strong_ciphersuites_for "gnutls")
4.146- fi
4.147- fi
4.148-
4.149- RETVAL="$_cs"
4.150-}
4.151-
4.152-check_help_for() {
4.153- local _arch
4.154- local _cmd
4.155- local _arg
4.156- _arch="$1"
4.157- shift
4.158- _cmd="$1"
4.159- shift
4.160-
4.161- local _category
4.162- if "$_cmd" --help | grep -q 'For all options use the manual or "--help all".'; then
4.163- _category="all"
4.164- else
4.165- _category=""
4.166- fi
4.167-
4.168- case "$_arch" in
4.169-
4.170- *darwin*)
4.171- if check_cmd sw_vers; then
4.172- case $(sw_vers -productVersion) in
4.173- 10.*)
4.174- # If we're running on macOS, older than 10.13, then we always
4.175- # fail to find these options to force fallback
4.176- if [ "$(sw_vers -productVersion | cut -d. -f2)" -lt 13 ]; then
4.177- # Older than 10.13
4.178- echo "Warning: Detected macOS platform older than 10.13"
4.179- return 1
4.180- fi
4.181- ;;
4.182- 11.*)
4.183- # We assume Big Sur will be OK for now
4.184- ;;
4.185- *)
4.186- # Unknown product version, warn and continue
4.187- echo "Warning: Detected unknown macOS major version: $(sw_vers -productVersion)"
4.188- echo "Warning TLS capabilities detection may fail"
4.189- ;;
4.190- esac
4.191- fi
4.192- ;;
4.193-
4.194- esac
4.195-
4.196- for _arg in "$@"; do
4.197- if ! "$_cmd" --help "$_category" | grep -q -- "$_arg"; then
4.198- return 1
4.199- fi
4.200- done
4.201-
4.202- true # not strictly needed
4.203-}
4.204-
4.205-# Return strong TLS 1.2-1.3 cipher suites in OpenSSL or GnuTLS syntax. TLS 1.2
4.206-# excludes non-ECDHE and non-AEAD cipher suites. DHE is excluded due to bad
4.207-# DH params often found on servers (see RFC 7919). Sequence matches or is
4.208-# similar to Firefox 68 ESR with weak cipher suites disabled via about:config.
4.209-# $1 must be openssl or gnutls.
4.210-get_strong_ciphersuites_for() {
4.211- if [ "$1" = "openssl" ]; then
4.212- # OpenSSL is forgiving of unknown values, no problems with TLS 1.3 values on versions that don't support it yet.
4.213- echo "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"
4.214- elif [ "$1" = "gnutls" ]; then
4.215- # GnuTLS isn't forgiving of unknown values, so this may require a GnuTLS version that supports TLS 1.3 even if wget doesn't.
4.216- # Begin with SECURE128 (and higher) then remove/add to build cipher suites. Produces same 9 cipher suites as OpenSSL but in slightly different order.
4.217- echo "SECURE128:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-DTLS-ALL:-CIPHER-ALL:-MAC-ALL:-KX-ALL:+AEAD:+ECDHE-ECDSA:+ECDHE-RSA:+AES-128-GCM:+CHACHA20-POLY1305:+AES-256-GCM"
4.218- fi
4.219-}
4.220-
4.221-check_proc() {
4.222- # Check for /proc by looking for the /proc/self/exe link
4.223- # This is only run on Linux
4.224- if ! test -L /proc/self/exe ; then
4.225- err "fatal: Unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc."
4.226- fi
4.227-}
4.228-
4.229-get_bitness() {
4.230- need_cmd head
4.231- # Architecture detection without dependencies beyond coreutils.
4.232- # ELF files start out "\x7fELF", and the following byte is
4.233- # 0x01 for 32-bit and
4.234- # 0x02 for 64-bit.
4.235- # The printf builtin on some shells like dash only supports octal
4.236- # escape sequences, so we use those.
4.237- local _current_exe_head
4.238- _current_exe_head=$(head -c 5 /proc/self/exe )
4.239- if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then
4.240- echo 32
4.241- elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then
4.242- echo 64
4.243- else
4.244- err "unknown platform bitness"
4.245- fi
4.246-}
4.247-
4.248-is_host_amd64_elf() {
4.249- need_cmd head
4.250- need_cmd tail
4.251- # ELF e_machine detection without dependencies beyond coreutils.
4.252- # Two-byte field at offset 0x12 indicates the CPU,
4.253- # but we're interested in it being 0x3E to indicate amd64, or not that.
4.254- local _current_exe_machine
4.255- _current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1)
4.256- [ "$_current_exe_machine" = "$(printf '\076')" ]
4.257-}
4.258-
4.259-get_endianness() {
4.260- local cputype=$1
4.261- local suffix_eb=$2
4.262- local suffix_el=$3
4.263-
4.264- # detect endianness without od/hexdump, like get_bitness() does.
4.265- need_cmd head
4.266- need_cmd tail
4.267-
4.268- local _current_exe_endianness
4.269- _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)"
4.270- if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then
4.271- echo "${cputype}${suffix_el}"
4.272- elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then
4.273- echo "${cputype}${suffix_eb}"
4.274- else
4.275- err "unknown platform endianness"
4.276- fi
4.277-}
4.278-
4.279-get_architecture() {
4.280- local _ostype _cputype _bitness _arch _clibtype
4.281- _ostype="$(uname -s)"
4.282- _cputype="$(uname -m)"
4.283- _clibtype="gnu"
4.284-
4.285- if [ "$_ostype" = Linux ]; then
4.286- if [ "$(uname -o)" = Android ]; then
4.287- _ostype=Android
4.288- fi
4.289- if ldd --version 2>&1 | grep -q 'musl'; then
4.290- _clibtype="musl"
4.291- fi
4.292- fi
4.293-
4.294- if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then
4.295- # Darwin `uname -m` lies
4.296- if sysctl hw.optional.x86_64 | grep -q ': 1'; then
4.297- _cputype=x86_64
4.298- fi
4.299- fi
4.300-
4.301- if [ "$_ostype" = SunOS ]; then
4.302- # Both Solaris and illumos presently announce as "SunOS" in "uname -s"
4.303- # so use "uname -o" to disambiguate. We use the full path to the
4.304- # system uname in case the user has coreutils uname first in PATH,
4.305- # which has historically sometimes printed the wrong value here.
4.306- if [ "$(/usr/bin/uname -o)" = illumos ]; then
4.307- _ostype=illumos
4.308- fi
4.309-
4.310- # illumos systems have multi-arch userlands, and "uname -m" reports the
4.311- # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86
4.312- # systems. Check for the native (widest) instruction set on the
4.313- # running kernel:
4.314- if [ "$_cputype" = i86pc ]; then
4.315- _cputype="$(isainfo -n)"
4.316- fi
4.317- fi
4.318-
4.319- case "$_ostype" in
4.320-
4.321- Android)
4.322- _ostype=linux-android
4.323- ;;
4.324-
4.325- Linux)
4.326- check_proc
4.327- _ostype=unknown-linux-$_clibtype
4.328- _bitness=$(get_bitness)
4.329- ;;
4.330-
4.331- FreeBSD)
4.332- _ostype=unknown-freebsd
4.333- ;;
4.334-
4.335- NetBSD)
4.336- _ostype=unknown-netbsd
4.337- ;;
4.338-
4.339- DragonFly)
4.340- _ostype=unknown-dragonfly
4.341- ;;
4.342-
4.343- Darwin)
4.344- _ostype=apple-darwin
4.345- ;;
4.346-
4.347- illumos)
4.348- _ostype=unknown-illumos
4.349- ;;
4.350-
4.351- MINGW* | MSYS* | CYGWIN* | Windows_NT)
4.352- _ostype=pc-windows-gnu
4.353- ;;
4.354-
4.355- *)
4.356- err "unrecognized OS type: $_ostype"
4.357- ;;
4.358-
4.359- esac
4.360-
4.361- case "$_cputype" in
4.362-
4.363- i386 | i486 | i686 | i786 | x86)
4.364- _cputype=i686
4.365- ;;
4.366-
4.367- xscale | arm)
4.368- _cputype=arm
4.369- if [ "$_ostype" = "linux-android" ]; then
4.370- _ostype=linux-androideabi
4.371- fi
4.372- ;;
4.373-
4.374- armv6l)
4.375- _cputype=arm
4.376- if [ "$_ostype" = "linux-android" ]; then
4.377- _ostype=linux-androideabi
4.378- else
4.379- _ostype="${_ostype}eabihf"
4.380- fi
4.381- ;;
4.382-
4.383- armv7l | armv8l)
4.384- _cputype=armv7
4.385- if [ "$_ostype" = "linux-android" ]; then
4.386- _ostype=linux-androideabi
4.387- else
4.388- _ostype="${_ostype}eabihf"
4.389- fi
4.390- ;;
4.391-
4.392- aarch64 | arm64)
4.393- _cputype=aarch64
4.394- ;;
4.395-
4.396- x86_64 | x86-64 | x64 | amd64)
4.397- _cputype=x86_64
4.398- ;;
4.399-
4.400- mips)
4.401- _cputype=$(get_endianness mips '' el)
4.402- ;;
4.403-
4.404- mips64)
4.405- if [ "$_bitness" -eq 64 ]; then
4.406- # only n64 ABI is supported for now
4.407- _ostype="${_ostype}abi64"
4.408- _cputype=$(get_endianness mips64 '' el)
4.409- fi
4.410- ;;
4.411-
4.412- ppc)
4.413- _cputype=powerpc
4.414- ;;
4.415-
4.416- ppc64)
4.417- _cputype=powerpc64
4.418- ;;
4.419-
4.420- ppc64le)
4.421- _cputype=powerpc64le
4.422- ;;
4.423-
4.424- s390x)
4.425- _cputype=s390x
4.426- ;;
4.427- riscv64)
4.428- _cputype=riscv64gc
4.429- ;;
4.430- loongarch64)
4.431- _cputype=loongarch64
4.432- ;;
4.433- *)
4.434- err "unknown CPU type: $_cputype"
4.435-
4.436- esac
4.437-
4.438- # Detect 64-bit linux with 32-bit userland
4.439- if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then
4.440- case $_cputype in
4.441- x86_64)
4.442- if [ -n "${CPUTYPE:-}" ]; then
4.443- _cputype="$CPUTYPE"
4.444- else {
4.445- # 32-bit executable for amd64 = x32
4.446- if is_host_amd64_elf; then {
4.447- echo "This host is running an x32 userland; as it stands, x32 support is poor," 1>&2
4.448- echo "and there isn't a native toolchain -- you will have to install" 1>&2
4.449- echo "multiarch compatibility with i686 and/or amd64, then select one" 1>&2
4.450- echo "by re-running this script with the CPUTYPE environment variable" 1>&2
4.451- echo "set to i686 or x86_64, respectively." 1>&2
4.452- exit 1
4.453- }; else
4.454- _cputype=i686
4.455- fi
4.456- }; fi
4.457- ;;
4.458- mips64)
4.459- _cputype=$(get_endianness mips '' el)
4.460- ;;
4.461- powerpc64)
4.462- _cputype=powerpc
4.463- ;;
4.464- aarch64)
4.465- _cputype=armv7
4.466- if [ "$_ostype" = "linux-android" ]; then
4.467- _ostype=linux-androideabi
4.468- else
4.469- _ostype="${_ostype}eabihf"
4.470- fi
4.471- ;;
4.472- riscv64gc)
4.473- err "riscv64 with 32-bit userland unsupported"
4.474- ;;
4.475- esac
4.476- fi
4.477-
4.478- if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then
4.479- if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then
4.480- # At least one processor does not have NEON.
4.481- _cputype=arm
4.482- fi
4.483- fi
4.484-
4.485- _arch="${_cputype}-${_ostype}"
4.486-
4.487- RETVAL="$_arch"
4.488-}
4.489-
4.490-# This wraps curl or wget. Try curl first, if not installed,
4.491-# use wget instead.
4.492-download() {
4.493- local _dld
4.494- local _ciphersuites
4.495- local _err
4.496- local _status
4.497- local _retry
4.498- if check_cmd curl; then
4.499- _dld=curl
4.500- elif check_cmd wget; then
4.501- _dld=wget
4.502- else
4.503- _dld='curl or wget' # to be used in error message of need_cmd
4.504- fi
4.505-
4.506- if [ "$1" = --check ]; then
4.507- need_cmd "$_dld"
4.508- elif [ "$_dld" = curl ]; then
4.509- check_curl_for_retry_support
4.510- _retry="$RETVAL"
4.511- get_ciphersuites_for_curl
4.512- _ciphersuites="$RETVAL"
4.513- if [ -n "$_ciphersuites" ]; then
4.514- _err=$(curl $_retry --proto '=https' --tlsv1.2 --ciphers "$_ciphersuites" --silent --show-error --fail --location "$1" --output "$2" 2>&1)
4.515- _status=$?
4.516- else
4.517- echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
4.518- if ! check_help_for "$3" curl --proto --tlsv1.2; then
4.519- echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
4.520- _err=$(curl $_retry --silent --show-error --fail --location "$1" --output "$2" 2>&1)
4.521- _status=$?
4.522- else
4.523- _err=$(curl $_retry --proto '=https' --tlsv1.2 --silent --show-error --fail --location "$1" --output "$2" 2>&1)
4.524- _status=$?
4.525- fi
4.526- fi
4.527- if [ -n "$_err" ]; then
4.528- echo "$_err" >&2
4.529- if echo "$_err" | grep -q 404$; then
4.530- err "installer for platform '$3' not found, this may be unsupported"
4.531- fi
4.532- fi
4.533- return $_status
4.534- elif [ "$_dld" = wget ]; then
4.535- if [ "$(wget -V 2>&1|head -2|tail -1|cut -f1 -d" ")" = "BusyBox" ]; then
4.536- echo "Warning: using the BusyBox version of wget. Not enforcing strong cipher suites for TLS or TLS v1.2, this is potentially less secure"
4.537- _err=$(wget "$1" -O "$2" 2>&1)
4.538- _status=$?
4.539- else
4.540- get_ciphersuites_for_wget
4.541- _ciphersuites="$RETVAL"
4.542- if [ -n "$_ciphersuites" ]; then
4.543- _err=$(wget --https-only --secure-protocol=TLSv1_2 --ciphers "$_ciphersuites" "$1" -O "$2" 2>&1)
4.544- _status=$?
4.545- else
4.546- echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
4.547- if ! check_help_for "$3" wget --https-only --secure-protocol; then
4.548- echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
4.549- _err=$(wget "$1" -O "$2" 2>&1)
4.550- _status=$?
4.551- else
4.552- _err=$(wget --https-only --secure-protocol=TLSv1_2 "$1" -O "$2" 2>&1)
4.553- _status=$?
4.554- fi
4.555- fi
4.556- fi
4.557- if [ -n "$_err" ]; then
4.558- echo "$_err" >&2
4.559- if echo "$_err" | grep -q ' 404 Not Found$'; then
4.560- err "installer for platform '$3' not found, this may be unsupported"
4.561- fi
4.562- fi
4.563- return $_status
4.564- else
4.565- err "Unknown downloader" # should not reach here
4.566- fi
4.567-}
4.568-
4.569-main "$@" || exit 1