changeset 18: |
d15e540441fd |
parent 17: |
aac1cf6cf2bb |
child 19: |
9b2e35556a96 |
author: |
ellis <ellis@rwest.io> |
date: |
Sun, 03 Dec 2023 18:44:34 -0500 |
files: |
scripts/init.sh |
description: |
added core init script |
1.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2+++ b/scripts/init.sh Sun Dec 03 18:44:34 2023 -0500
1.3@@ -0,0 +1,679 @@
1.4+#!/bin/sh
1.5+
1.6+# install the compiler.company installer.
1.7+
1.8+set -u
1.9+
1.10+COMPANY_UPDATE_ROOT="${COMPANY_UPDATE_ROOT:-https://packy.compiler.company/dist}"
1.11+
1.12+# NOTICE: If you change anything here, please make the same changes in setup_mode.rs
1.13+usage() {
1.14+ cat <<EOF
1.15+cc-init 0.10 (0941fa04c53d+ 2023-12-03)
1.16+The compiler.company installer
1.17+
1.18+USAGE:
1.19+ cc-init [OPTIONS]
1.20+
1.21+OPTIONS:
1.22+ -y Disable confirmation prompt.
1.23+ -h, --help
1.24+ Print help information
1.25+ -V, --version
1.26+ Print version information
1.27+EOF
1.28+}
1.29+
1.30+main() {
1.31+ downloader --check
1.32+ need_cmd uname
1.33+ need_cmd mktemp
1.34+ need_cmd chmod
1.35+ need_cmd mkdir
1.36+ need_cmd rm
1.37+ need_cmd rmdir
1.38+
1.39+ get_architecture || return 1
1.40+ local _arch="$RETVAL"
1.41+ assert_nz "$_arch" "arch"
1.42+
1.43+ local _ext=""
1.44+ case "$_arch" in
1.45+ *windows*)
1.46+ _ext=".exe"
1.47+ ;;
1.48+ esac
1.49+
1.50+ local _url="${COMPANY_UPDATE_ROOT}/${_arch}/cc-init${_ext}"
1.51+
1.52+ local _dir
1.53+ if ! _dir="$(ensure mktemp -d)"; then
1.54+ # Because the previous command ran in a subshell, we must manually
1.55+ # propagate exit status.
1.56+ exit 1
1.57+ fi
1.58+ local _file="${_dir}/cc-init${_ext}"
1.59+
1.60+ local _ansi_escapes_are_valid=false
1.61+ if [ -t 2 ]; then
1.62+ if [ "${TERM+set}" = 'set' ]; then
1.63+ case "$TERM" in
1.64+ xterm*|rxvt*|urxvt*|linux*|vt*)
1.65+ _ansi_escapes_are_valid=true
1.66+ ;;
1.67+ esac
1.68+ fi
1.69+ fi
1.70+
1.71+ # check if we have to use /dev/tty to prompt the user
1.72+ local need_tty=yes
1.73+ for arg in "$@"; do
1.74+ case "$arg" in
1.75+ --help)
1.76+ usage
1.77+ exit 0
1.78+ ;;
1.79+ *)
1.80+ OPTIND=1
1.81+ if [ "${arg%%--*}" = "" ]; then
1.82+ # Long option (other than --help);
1.83+ # don't attempt to interpret it.
1.84+ continue
1.85+ fi
1.86+ while getopts :hy sub_arg "$arg"; do
1.87+ case "$sub_arg" in
1.88+ h)
1.89+ usage
1.90+ exit 0
1.91+ ;;
1.92+ y)
1.93+ # user wants to skip the prompt --
1.94+ # we don't need /dev/tty
1.95+ need_tty=no
1.96+ ;;
1.97+ *)
1.98+ ;;
1.99+ esac
1.100+ done
1.101+ ;;
1.102+ esac
1.103+ done
1.104+
1.105+ if $_ansi_escapes_are_valid; then
1.106+ printf "\33[1minfo:\33[0m downloading installer\n" 1>&2
1.107+ else
1.108+ printf '%s\n' 'info: downloading installer' 1>&2
1.109+ fi
1.110+
1.111+ ensure mkdir -p "$_dir"
1.112+ ensure downloader "$_url" "$_file" "$_arch"
1.113+ ensure chmod u+x "$_file"
1.114+ if [ ! -x "$_file" ]; then
1.115+ printf '%s\n' "Cannot execute $_file (likely because of mounting /tmp as noexec)." 1>&2
1.116+ printf '%s\n' "Please copy the file to a location where you can execute binaries and run ./cc-init${_ext}." 1>&2
1.117+ exit 1
1.118+ fi
1.119+
1.120+ if [ "$need_tty" = "yes" ] && [ ! -t 0 ]; then
1.121+ # The installer is going to want to ask for confirmation by
1.122+ # reading stdin. This script was piped into `sh` though and
1.123+ # doesn't have stdin to pass to its children. Instead we're going
1.124+ # to explicitly connect /dev/tty to the installer's stdin.
1.125+ if [ ! -t 1 ]; then
1.126+ err "Unable to run interactively. Run with -y to accept defaults, --help for additional options"
1.127+ fi
1.128+
1.129+ ignore "$_file" "$@" < /dev/tty
1.130+ else
1.131+ ignore "$_file" "$@"
1.132+ fi
1.133+
1.134+ local _retval=$?
1.135+
1.136+ ignore rm "$_file"
1.137+ ignore rmdir "$_dir"
1.138+
1.139+ return "$_retval"
1.140+}
1.141+
1.142+check_proc() {
1.143+ # Check for /proc by looking for the /proc/self/exe link
1.144+ # This is only run on Linux
1.145+ if ! test -L /proc/self/exe ; then
1.146+ err "fatal: Unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc."
1.147+ fi
1.148+}
1.149+
1.150+get_bitness() {
1.151+ need_cmd head
1.152+ # Architecture detection without dependencies beyond coreutils.
1.153+ # ELF files start out "\x7fELF", and the following byte is
1.154+ # 0x01 for 32-bit and
1.155+ # 0x02 for 64-bit.
1.156+ # The printf builtin on some shells like dash only supports octal
1.157+ # escape sequences, so we use those.
1.158+ local _current_exe_head
1.159+ _current_exe_head=$(head -c 5 /proc/self/exe )
1.160+ if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then
1.161+ echo 32
1.162+ elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then
1.163+ echo 64
1.164+ else
1.165+ err "unknown platform bitness"
1.166+ fi
1.167+}
1.168+
1.169+is_host_amd64_elf() {
1.170+ need_cmd head
1.171+ need_cmd tail
1.172+ # ELF e_machine detection without dependencies beyond coreutils.
1.173+ # Two-byte field at offset 0x12 indicates the CPU,
1.174+ # but we're interested in it being 0x3E to indicate amd64, or not that.
1.175+ local _current_exe_machine
1.176+ _current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1)
1.177+ [ "$_current_exe_machine" = "$(printf '\076')" ]
1.178+}
1.179+
1.180+get_endianness() {
1.181+ local cputype=$1
1.182+ local suffix_eb=$2
1.183+ local suffix_el=$3
1.184+
1.185+ # detect endianness without od/hexdump, like get_bitness() does.
1.186+ need_cmd head
1.187+ need_cmd tail
1.188+
1.189+ local _current_exe_endianness
1.190+ _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)"
1.191+ if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then
1.192+ echo "${cputype}${suffix_el}"
1.193+ elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then
1.194+ echo "${cputype}${suffix_eb}"
1.195+ else
1.196+ err "unknown platform endianness"
1.197+ fi
1.198+}
1.199+
1.200+get_architecture() {
1.201+ local _ostype _cputype _bitness _arch _clibtype
1.202+ _ostype="$(uname -s)"
1.203+ _cputype="$(uname -m)"
1.204+ _clibtype="gnu"
1.205+
1.206+ if [ "$_ostype" = Linux ]; then
1.207+ if [ "$(uname -o)" = Android ]; then
1.208+ _ostype=Android
1.209+ fi
1.210+ if ldd --version 2>&1 | grep -q 'musl'; then
1.211+ _clibtype="musl"
1.212+ fi
1.213+ fi
1.214+
1.215+ if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then
1.216+ # Darwin `uname -m` lies
1.217+ if sysctl hw.optional.x86_64 | grep -q ': 1'; then
1.218+ _cputype=x86_64
1.219+ fi
1.220+ fi
1.221+
1.222+ if [ "$_ostype" = SunOS ]; then
1.223+ # Both Solaris and illumos presently announce as "SunOS" in "uname -s"
1.224+ # so use "uname -o" to disambiguate. We use the full path to the
1.225+ # system uname in case the user has coreutils uname first in PATH,
1.226+ # which has historically sometimes printed the wrong value here.
1.227+ if [ "$(/usr/bin/uname -o)" = illumos ]; then
1.228+ _ostype=illumos
1.229+ fi
1.230+
1.231+ # illumos systems have multi-arch userlands, and "uname -m" reports the
1.232+ # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86
1.233+ # systems. Check for the native (widest) instruction set on the
1.234+ # running kernel:
1.235+ if [ "$_cputype" = i86pc ]; then
1.236+ _cputype="$(isainfo -n)"
1.237+ fi
1.238+ fi
1.239+
1.240+ case "$_ostype" in
1.241+
1.242+ Android)
1.243+ _ostype=linux-android
1.244+ ;;
1.245+
1.246+ Linux)
1.247+ check_proc
1.248+ _ostype=unknown-linux-$_clibtype
1.249+ _bitness=$(get_bitness)
1.250+ ;;
1.251+
1.252+ FreeBSD)
1.253+ _ostype=unknown-freebsd
1.254+ ;;
1.255+
1.256+ NetBSD)
1.257+ _ostype=unknown-netbsd
1.258+ ;;
1.259+
1.260+ DragonFly)
1.261+ _ostype=unknown-dragonfly
1.262+ ;;
1.263+
1.264+ Darwin)
1.265+ _ostype=apple-darwin
1.266+ ;;
1.267+
1.268+ illumos)
1.269+ _ostype=unknown-illumos
1.270+ ;;
1.271+
1.272+ MINGW* | MSYS* | CYGWIN* | Windows_NT)
1.273+ _ostype=pc-windows-gnu
1.274+ ;;
1.275+
1.276+ *)
1.277+ err "unrecognized OS type: $_ostype"
1.278+ ;;
1.279+
1.280+ esac
1.281+
1.282+ case "$_cputype" in
1.283+
1.284+ i386 | i486 | i686 | i786 | x86)
1.285+ _cputype=i686
1.286+ ;;
1.287+
1.288+ xscale | arm)
1.289+ _cputype=arm
1.290+ if [ "$_ostype" = "linux-android" ]; then
1.291+ _ostype=linux-androideabi
1.292+ fi
1.293+ ;;
1.294+
1.295+ armv6l)
1.296+ _cputype=arm
1.297+ if [ "$_ostype" = "linux-android" ]; then
1.298+ _ostype=linux-androideabi
1.299+ else
1.300+ _ostype="${_ostype}eabihf"
1.301+ fi
1.302+ ;;
1.303+
1.304+ armv7l | armv8l)
1.305+ _cputype=armv7
1.306+ if [ "$_ostype" = "linux-android" ]; then
1.307+ _ostype=linux-androideabi
1.308+ else
1.309+ _ostype="${_ostype}eabihf"
1.310+ fi
1.311+ ;;
1.312+
1.313+ aarch64 | arm64)
1.314+ _cputype=aarch64
1.315+ ;;
1.316+
1.317+ x86_64 | x86-64 | x64 | amd64)
1.318+ _cputype=x86_64
1.319+ ;;
1.320+
1.321+ mips)
1.322+ _cputype=$(get_endianness mips '' el)
1.323+ ;;
1.324+
1.325+ mips64)
1.326+ if [ "$_bitness" -eq 64 ]; then
1.327+ # only n64 ABI is supported for now
1.328+ _ostype="${_ostype}abi64"
1.329+ _cputype=$(get_endianness mips64 '' el)
1.330+ fi
1.331+ ;;
1.332+
1.333+ ppc)
1.334+ _cputype=powerpc
1.335+ ;;
1.336+
1.337+ ppc64)
1.338+ _cputype=powerpc64
1.339+ ;;
1.340+
1.341+ ppc64le)
1.342+ _cputype=powerpc64le
1.343+ ;;
1.344+
1.345+ s390x)
1.346+ _cputype=s390x
1.347+ ;;
1.348+ riscv64)
1.349+ _cputype=riscv64gc
1.350+ ;;
1.351+ loongarch64)
1.352+ _cputype=loongarch64
1.353+ ;;
1.354+ *)
1.355+ err "unknown CPU type: $_cputype"
1.356+
1.357+ esac
1.358+
1.359+ # Detect 64-bit linux with 32-bit userland
1.360+ if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then
1.361+ case $_cputype in
1.362+ x86_64)
1.363+ if [ -n "${CPUTYPE:-}" ]; then
1.364+ _cputype="$CPUTYPE"
1.365+ else {
1.366+ # 32-bit executable for amd64 = x32
1.367+ if is_host_amd64_elf; then {
1.368+ echo "This host is running an x32 userland; as it stands, x32 support is poor," 1>&2
1.369+ echo "and there isn't a native toolchain -- you will have to install" 1>&2
1.370+ echo "multiarch compatibility with i686 and/or amd64, then select one" 1>&2
1.371+ echo "by re-running this script with the CPUTYPE environment variable" 1>&2
1.372+ echo "set to i686 or x86_64, respectively." 1>&2
1.373+ exit 1
1.374+ }; else
1.375+ _cputype=i686
1.376+ fi
1.377+ }; fi
1.378+ ;;
1.379+ mips64)
1.380+ _cputype=$(get_endianness mips '' el)
1.381+ ;;
1.382+ powerpc64)
1.383+ _cputype=powerpc
1.384+ ;;
1.385+ aarch64)
1.386+ _cputype=armv7
1.387+ if [ "$_ostype" = "linux-android" ]; then
1.388+ _ostype=linux-androideabi
1.389+ else
1.390+ _ostype="${_ostype}eabihf"
1.391+ fi
1.392+ ;;
1.393+ riscv64gc)
1.394+ err "riscv64 with 32-bit userland unsupported"
1.395+ ;;
1.396+ esac
1.397+ fi
1.398+
1.399+ if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then
1.400+ if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then
1.401+ # At least one processor does not have NEON.
1.402+ _cputype=arm
1.403+ fi
1.404+ fi
1.405+
1.406+ _arch="${_cputype}-${_ostype}"
1.407+
1.408+ RETVAL="$_arch"
1.409+}
1.410+
1.411+say() {
1.412+ printf 'compiler.company: %s\n' "$1"
1.413+}
1.414+
1.415+err() {
1.416+ say "$1" >&2
1.417+ exit 1
1.418+}
1.419+
1.420+need_cmd() {
1.421+ if ! check_cmd "$1"; then
1.422+ err "need '$1' (command not found)"
1.423+ fi
1.424+}
1.425+
1.426+check_cmd() {
1.427+ command -v "$1" > /dev/null 2>&1
1.428+}
1.429+
1.430+assert_nz() {
1.431+ if [ -z "$1" ]; then err "assert_nz $2"; fi
1.432+}
1.433+
1.434+# Run a command that should never fail. If the command fails execution
1.435+# will immediately terminate with an error showing the failing
1.436+# command.
1.437+ensure() {
1.438+ if ! "$@"; then err "command failed: $*"; fi
1.439+}
1.440+
1.441+# This is just for indicating that commands' results are being
1.442+# intentionally ignored. Usually, because it's being executed
1.443+# as part of error handling.
1.444+ignore() {
1.445+ "$@"
1.446+}
1.447+
1.448+# This wraps curl or wget. Try curl first, if not installed,
1.449+# use wget instead.
1.450+downloader() {
1.451+ local _dld
1.452+ local _ciphersuites
1.453+ local _err
1.454+ local _status
1.455+ local _retry
1.456+ if check_cmd curl; then
1.457+ _dld=curl
1.458+ elif check_cmd wget; then
1.459+ _dld=wget
1.460+ else
1.461+ _dld='curl or wget' # to be used in error message of need_cmd
1.462+ fi
1.463+
1.464+ if [ "$1" = --check ]; then
1.465+ need_cmd "$_dld"
1.466+ elif [ "$_dld" = curl ]; then
1.467+ check_curl_for_retry_support
1.468+ _retry="$RETVAL"
1.469+ get_ciphersuites_for_curl
1.470+ _ciphersuites="$RETVAL"
1.471+ if [ -n "$_ciphersuites" ]; then
1.472+ _err=$(curl $_retry --proto '=https' --tlsv1.2 --ciphers "$_ciphersuites" --silent --show-error --fail --location "$1" --output "$2" 2>&1)
1.473+ _status=$?
1.474+ else
1.475+ echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
1.476+ if ! check_help_for "$3" curl --proto --tlsv1.2; then
1.477+ echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
1.478+ _err=$(curl $_retry --silent --show-error --fail --location "$1" --output "$2" 2>&1)
1.479+ _status=$?
1.480+ else
1.481+ _err=$(curl $_retry --proto '=https' --tlsv1.2 --silent --show-error --fail --location "$1" --output "$2" 2>&1)
1.482+ _status=$?
1.483+ fi
1.484+ fi
1.485+ if [ -n "$_err" ]; then
1.486+ echo "$_err" >&2
1.487+ if echo "$_err" | grep -q 404$; then
1.488+ err "installer for platform '$3' not found, this may be unsupported"
1.489+ fi
1.490+ fi
1.491+ return $_status
1.492+ elif [ "$_dld" = wget ]; then
1.493+ if [ "$(wget -V 2>&1|head -2|tail -1|cut -f1 -d" ")" = "BusyBox" ]; then
1.494+ 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.495+ _err=$(wget "$1" -O "$2" 2>&1)
1.496+ _status=$?
1.497+ else
1.498+ get_ciphersuites_for_wget
1.499+ _ciphersuites="$RETVAL"
1.500+ if [ -n "$_ciphersuites" ]; then
1.501+ _err=$(wget --https-only --secure-protocol=TLSv1_2 --ciphers "$_ciphersuites" "$1" -O "$2" 2>&1)
1.502+ _status=$?
1.503+ else
1.504+ echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
1.505+ if ! check_help_for "$3" wget --https-only --secure-protocol; then
1.506+ echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
1.507+ _err=$(wget "$1" -O "$2" 2>&1)
1.508+ _status=$?
1.509+ else
1.510+ _err=$(wget --https-only --secure-protocol=TLSv1_2 "$1" -O "$2" 2>&1)
1.511+ _status=$?
1.512+ fi
1.513+ fi
1.514+ fi
1.515+ if [ -n "$_err" ]; then
1.516+ echo "$_err" >&2
1.517+ if echo "$_err" | grep -q ' 404 Not Found$'; then
1.518+ err "installer for platform '$3' not found, this may be unsupported"
1.519+ fi
1.520+ fi
1.521+ return $_status
1.522+ else
1.523+ err "Unknown downloader" # should not reach here
1.524+ fi
1.525+}
1.526+
1.527+check_help_for() {
1.528+ local _arch
1.529+ local _cmd
1.530+ local _arg
1.531+ _arch="$1"
1.532+ shift
1.533+ _cmd="$1"
1.534+ shift
1.535+
1.536+ local _category
1.537+ if "$_cmd" --help | grep -q 'For all options use the manual or "--help all".'; then
1.538+ _category="all"
1.539+ else
1.540+ _category=""
1.541+ fi
1.542+
1.543+ case "$_arch" in
1.544+
1.545+ *darwin*)
1.546+ if check_cmd sw_vers; then
1.547+ case $(sw_vers -productVersion) in
1.548+ 10.*)
1.549+ # If we're running on macOS, older than 10.13, then we always
1.550+ # fail to find these options to force fallback
1.551+ if [ "$(sw_vers -productVersion | cut -d. -f2)" -lt 13 ]; then
1.552+ # Older than 10.13
1.553+ echo "Warning: Detected macOS platform older than 10.13"
1.554+ return 1
1.555+ fi
1.556+ ;;
1.557+ 11.*)
1.558+ # We assume Big Sur will be OK for now
1.559+ ;;
1.560+ *)
1.561+ # Unknown product version, warn and continue
1.562+ echo "Warning: Detected unknown macOS major version: $(sw_vers -productVersion)"
1.563+ echo "Warning TLS capabilities detection may fail"
1.564+ ;;
1.565+ esac
1.566+ fi
1.567+ ;;
1.568+
1.569+ esac
1.570+
1.571+ for _arg in "$@"; do
1.572+ if ! "$_cmd" --help "$_category" | grep -q -- "$_arg"; then
1.573+ return 1
1.574+ fi
1.575+ done
1.576+
1.577+ true # not strictly needed
1.578+}
1.579+
1.580+# Check if curl supports the --retry flag, then pass it to the curl invocation.
1.581+check_curl_for_retry_support() {
1.582+ local _retry_supported=""
1.583+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
1.584+ if check_help_for "notspecified" "curl" "--retry"; then
1.585+ _retry_supported="--retry 3"
1.586+ if check_help_for "notspecified" "curl" "--continue-at"; then
1.587+ # "-C -" tells curl to automatically find where to resume the download when retrying.
1.588+ _retry_supported="--retry 3 -C -"
1.589+ fi
1.590+ fi
1.591+
1.592+ RETVAL="$_retry_supported"
1.593+}
1.594+
1.595+# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
1.596+# if support by local tools is detected. Detection currently supports these curl backends:
1.597+# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
1.598+get_ciphersuites_for_curl() {
1.599+ if [ -n "${COMPANY_TLS_CIPHERSUITES-}" ]; then
1.600+ # user specified custom cipher suites, assume they know what they're doing
1.601+ RETVAL="$COMPANY_TLS_CIPHERSUITES"
1.602+ return
1.603+ fi
1.604+
1.605+ local _openssl_syntax="no"
1.606+ local _gnutls_syntax="no"
1.607+ local _backend_supported="yes"
1.608+ if curl -V | grep -q ' OpenSSL/'; then
1.609+ _openssl_syntax="yes"
1.610+ elif curl -V | grep -iq ' LibreSSL/'; then
1.611+ _openssl_syntax="yes"
1.612+ elif curl -V | grep -iq ' BoringSSL/'; then
1.613+ _openssl_syntax="yes"
1.614+ elif curl -V | grep -iq ' GnuTLS/'; then
1.615+ _gnutls_syntax="yes"
1.616+ else
1.617+ _backend_supported="no"
1.618+ fi
1.619+
1.620+ local _args_supported="no"
1.621+ if [ "$_backend_supported" = "yes" ]; then
1.622+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
1.623+ if check_help_for "notspecified" "curl" "--tlsv1.2" "--ciphers" "--proto"; then
1.624+ _args_supported="yes"
1.625+ fi
1.626+ fi
1.627+
1.628+ local _cs=""
1.629+ if [ "$_args_supported" = "yes" ]; then
1.630+ if [ "$_openssl_syntax" = "yes" ]; then
1.631+ _cs=$(get_strong_ciphersuites_for "openssl")
1.632+ elif [ "$_gnutls_syntax" = "yes" ]; then
1.633+ _cs=$(get_strong_ciphersuites_for "gnutls")
1.634+ fi
1.635+ fi
1.636+
1.637+ RETVAL="$_cs"
1.638+}
1.639+
1.640+# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
1.641+# if support by local tools is detected. Detection currently supports these wget backends:
1.642+# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
1.643+get_ciphersuites_for_wget() {
1.644+ if [ -n "${COMPANY_TLS_CIPHERSUITES-}" ]; then
1.645+ # user specified custom cipher suites, assume they know what they're doing
1.646+ RETVAL="$COMPANY_TLS_CIPHERSUITES"
1.647+ return
1.648+ fi
1.649+
1.650+ local _cs=""
1.651+ if wget -V | grep -q '\-DHAVE_LIBSSL'; then
1.652+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
1.653+ if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
1.654+ _cs=$(get_strong_ciphersuites_for "openssl")
1.655+ fi
1.656+ elif wget -V | grep -q '\-DHAVE_LIBGNUTLS'; then
1.657+ # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
1.658+ if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
1.659+ _cs=$(get_strong_ciphersuites_for "gnutls")
1.660+ fi
1.661+ fi
1.662+
1.663+ RETVAL="$_cs"
1.664+}
1.665+
1.666+# Return strong TLS 1.2-1.3 cipher suites in OpenSSL or GnuTLS syntax. TLS 1.2
1.667+# excludes non-ECDHE and non-AEAD cipher suites. DHE is excluded due to bad
1.668+# DH params often found on servers (see RFC 7919). Sequence matches or is
1.669+# similar to Firefox 68 ESR with weak cipher suites disabled via about:config.
1.670+# $1 must be openssl or gnutls.
1.671+get_strong_ciphersuites_for() {
1.672+ if [ "$1" = "openssl" ]; then
1.673+ # OpenSSL is forgiving of unknown values, no problems with TLS 1.3 values on versions that don't support it yet.
1.674+ 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.675+ elif [ "$1" = "gnutls" ]; then
1.676+ # 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.677+ # 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.678+ 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.679+ fi
1.680+}
1.681+
1.682+main "$@" || exit 1