changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > demo / tools/deps.sh

changeset 27: 529419ac94f3
author: ellis <ellis@rwest.io>
date: Tue, 06 Jun 2023 18:55:17 -0400
permissions: -rw-r--r--
description: refactor 2 (wip)
1 #!/usr/bin/sh
2 # install demo build dependencies
3 set -u
4 PKG_URL_ROOT="${PKG_URL_ROOT:-https://rwest.io/otom8/packy/bundle}"
5 PKG_NAME="demo_build_deps"
6 say() {printf 'babel-installer: %s\n' "$1"}
7 err() {say "$1" >&2; exit 1}
8 need_cmd() {
9  if ! check_cmd "$1"; then
10  err "need '$1' (command not found)"
11  fi}
12 check_cmd() {command -v "$1" > /dev/null 2>&1}
13 ensure() {if ! "$@"; then err "command failed: $*"; fi}
14 ignore() {"$@"}
15 
16 main () {
17  need_cmd chmod
18  need_cmd mkdir
19  need_cmd rm
20 
21  get_architecture || return 1
22  local _arch="$RETVAL"
23  assert_nz "$_arch" "arch"
24 
25  # no extension unless on windows
26  local _ext=""
27  case "$_arch" in
28  *windows*)
29  _ext=".exe"
30  ;;
31  esac
32 
33  local _url="${PKG_URL_ROOT}/bin/dist/${_arch}/${PKG_NAME}${_ext}"
34 
35  local _dir
36  _dir="$(ensure mktemp -d)"
37  local _file="${_dir}/${PKG_NAME}${_ext}"
38 
39  local _ansi_escapes_are_valid=false
40  if [ -t 2 ]; then
41  if [ "${TERM+set}" = 'set' ]; then
42  case "$TERM" in
43  xterm*|rxvt*|urxvt*|linux*|vt*)
44  _ansi_escapes_are_valid=true
45  ;;
46  esac
47  fi
48  fi
49 
50  # check if we have to use /dev/tty to prompt the user
51  local need_tty=yes
52  for arg in "$@"; do
53  case "$arg" in
54  q)
55  # user wants to skip the prompt --
56  # we don't need /dev/tty
57  need_tty=no
58  ;;
59  *)
60  ;;
61  esac
62  done
63 
64  if $_ansi_escapes_are_valid; then
65  printf "\33[1minfo:\33[0m downloading $PKG_NAME\n" 1>&2
66  else
67  printf '%s\n' 'info: downloading $PKG_NAME' 1>&2
68  fi
69 
70  ensure mkdir -p "$_dir"
71  ensure downloader "$_url" "$_file" "$_arch"
72  ensure chmod u+x "$_file"
73  if [ ! -x "$_file" ]; then
74  printf '%s\n' "Cannot execute $_file (likely because of mounting /tmp as noexec)." 1>&2
75  printf '%s\n' "Please copy the file to a location where you can execute binaries and run ./${PKG_NAME}${_ext}." 1>&2
76  exit 1
77  fi
78 
79  if [ "$need_tty" = "yes" ]; then
80  # The installer is going to want to ask for confirmation by
81  # reading stdin. This script was piped into `sh` though and
82  # doesn't have stdin to pass to its children. Instead we're going
83  # to explicitly connect /dev/tty to the installer's stdin.
84  if [ ! -t 1 ]; then
85  err "Unable to run interactively. Run with -y to accept defaults"
86  fi
87 
88  ignore "$_file" "$@" < /dev/tty
89  else
90  ignore "$_file" "$@"
91  fi
92 
93  local _retval=$?
94 
95  ignore rm "$_file"
96  ignore rmdir "$_dir"
97 
98  return "$_retval"
99 }
100 
101 dl() { # curl || wget
102  local _dld
103  local _ciphersuites
104  local _err
105  local _status
106  if check_cmd curl; then
107  _dld=curl
108  elif check_cmd wget; then
109  _dld=wget
110  else
111  _dld='curl or wget' # to be used in error message of need_cmd
112  fi
113 
114  if [ "$1" = --check ]; then
115  need_cmd "$_dld"
116  elif [ "$_dld" = curl ]; then
117  get_ciphersuites_for_curl
118  _ciphersuites="$RETVAL"
119  if [ -n "$_ciphersuites" ]; then
120  _err=$(curl --proto '=https' --tlsv1.2 --ciphers "$_ciphersuites" --silent --show-error --fail --location "$1" --output "$2" 2>&1)
121  _status=$?
122  else
123  echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
124  if ! check_help_for "$3" curl --proto --tlsv1.2; then
125  echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
126  _err=$(curl --silent --show-error --fail --location "$1" --output "$2" 2>&1)
127  _status=$?
128  else
129  _err=$(curl --proto '=https' --tlsv1.2 --silent --show-error --fail --location "$1" --output "$2" 2>&1)
130  _status=$?
131  fi
132  fi
133  if [ -n "$_err" ]; then
134  echo "$_err" >&2
135  if echo "$_err" | grep -q 404$; then
136  err "installer for platform '$3' not found 8^C - ask ellis to support your platform"
137  fi
138  fi
139  return $_status
140  elif [ "$_dld" = wget ]; then
141  get_ciphersuites_for_wget
142  _ciphersuites="$RETVAL"
143  if [ -n "$_ciphersuites" ]; then
144  _err=$(wget --https-only --secure-protocol=TLSv1_2 --ciphers "$_ciphersuites" "$1" -O "$2" 2>&1)
145  _status=$?
146  else
147  echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
148  if ! check_help_for "$3" wget --https-only --secure-protocol; then
149  echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
150  _err=$(wget "$1" -O "$2" 2>&1)
151  _status=$?
152  else
153  _err=$(wget --https-only --secure-protocol=TLSv1_2 "$1" -O "$2" 2>&1)
154  _status=$?
155  fi
156  fi
157  if [ -n "$_err" ]; then
158  echo "$_err" >&2
159  if echo "$_err" | grep -q ' 404 Not Found$'; then
160  err "installer for platform '$3' not found!"
161  fi
162  fi
163  return $_status
164  else
165  err "Unknown downloader" # should not reach here
166  fi
167 }
168 
169 check_help_for() {
170  local _arch
171  local _cmd
172  local _arg
173  _arch="$1"
174  shift
175  _cmd="$1"
176  shift
177 
178  local _category
179  if "$_cmd" --help | grep -q 'For all options use the manual or "--help all".'; then
180  _category="all"
181  else
182  _category=""
183  fi
184 
185  case "$_arch" in
186 
187  *darwin*)
188  if check_cmd sw_vers; then
189  case $(sw_vers -productVersion) in
190  10.*)
191  # If we're running on macOS, older than 10.13, then we always
192  # fail to find these options to force fallback
193  if [ "$(sw_vers -productVersion | cut -d. -f2)" -lt 13 ]; then
194  # Older than 10.13
195  echo "Warning: Detected macOS platform older than 10.13"
196  return 1
197  fi
198  ;;
199  11.*)
200  # We assume Big Sur will be OK for now
201  ;;
202  *)
203  # Unknown product version, warn and continue
204  echo "Warning: Detected unknown macOS major version: $(sw_vers -productVersion)"
205  echo "Warning TLS capabilities detection may fail"
206  ;;
207  esac
208  fi
209  ;;
210 
211  esac
212 
213  for _arg in "$@"; do
214  if ! "$_cmd" --help $_category | grep -q -- "$_arg"; then
215  return 1
216  fi
217  done
218 
219  true # not strictly needed
220 }
221 
222 # Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
223 # if support by local tools is detected. Detection currently supports these curl backends:
224 # GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
225 get_ciphersuites_for_curl() {
226  if [ -n "${BABEL_TLS_CIPHERSUITES-}" ]; then
227  # user specified custom cipher suites, assume they know what they're doing
228  RETVAL="$BABEL_TLS_CIPHERSUITES"
229  return
230  fi
231 
232  local _openssl_syntax="no"
233  local _gnutls_syntax="no"
234  local _backend_supported="yes"
235  if curl -V | grep -q ' OpenSSL/'; then
236  _openssl_syntax="yes"
237  elif curl -V | grep -iq ' LibreSSL/'; then
238  _openssl_syntax="yes"
239  elif curl -V | grep -iq ' BoringSSL/'; then
240  _openssl_syntax="yes"
241  elif curl -V | grep -iq ' GnuTLS/'; then
242  _gnutls_syntax="yes"
243  else
244  _backend_supported="no"
245  fi
246 
247  local _args_supported="no"
248  if [ "$_backend_supported" = "yes" ]; then
249  # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
250  if check_help_for "notspecified" "curl" "--tlsv1.2" "--ciphers" "--proto"; then
251  _args_supported="yes"
252  fi
253  fi
254 
255  local _cs=""
256  if [ "$_args_supported" = "yes" ]; then
257  if [ "$_openssl_syntax" = "yes" ]; then
258  _cs=$(get_strong_ciphersuites_for "openssl")
259  elif [ "$_gnutls_syntax" = "yes" ]; then
260  _cs=$(get_strong_ciphersuites_for "gnutls")
261  fi
262  fi
263 
264  RETVAL="$_cs"
265 }
266 
267 # Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
268 # if support by local tools is detected. Detection currently supports these wget backends:
269 # GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
270 get_ciphersuites_for_wget() {
271  if [ -n "${BABEL_TLS_CIPHERSUITES-}" ]; then
272  # user specified custom cipher suites, assume they know what they're doing
273  RETVAL="$BABEL_TLS_CIPHERSUITES"
274  return
275  fi
276 
277  local _cs=""
278  if wget -V | grep -q '\-DHAVE_LIBSSL'; then
279  # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
280  if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
281  _cs=$(get_strong_ciphersuites_for "openssl")
282  fi
283  elif wget -V | grep -q '\-DHAVE_LIBGNUTLS'; then
284  # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
285  if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
286  _cs=$(get_strong_ciphersuites_for "gnutls")
287  fi
288  fi
289 
290  RETVAL="$_cs"
291 }
292 
293 # Return strong TLS 1.2-1.3 cipher suites in OpenSSL or GnuTLS syntax. TLS 1.2
294 # excludes non-ECDHE and non-AEAD cipher suites. DHE is excluded due to bad
295 # DH params often found on servers (see RFC 7919). Sequence matches or is
296 # similar to Firefox 68 ESR with weak cipher suites disabled via about:config.
297 # $1 must be openssl or gnutls.
298 get_strong_ciphersuites_for() {
299  if [ "$1" = "openssl" ]; then
300  # OpenSSL is forgiving of unknown values, no problems with TLS 1.3 values on versions that don't support it yet.
301  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"
302  elif [ "$1" = "gnutls" ]; then
303  # GnuTLS isn't forgiving of unknown values, so this may require a GnuTLS version that supports TLS 1.3 even if wget doesn't.
304  # Begin with SECURE128 (and higher) then remove/add to build cipher suites. Produces same 9 cipher suites as OpenSSL but in slightly different order.
305  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"
306  fi
307 }
308 
309 main "$@" || exit 1