rustup-init.sh 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. #!/bin/sh
  2. # shellcheck shell=dash
  3. # This file is downloaded from https://sh.rustup.rs
  4. # This is just a little script that can be downloaded from the internet to
  5. # install rustup. It just does platform detection, downloads the installer
  6. # and runs it.
  7. # It runs on Unix shells like {a,ba,da,k,z}sh. It uses the common `local`
  8. # extension. Note: Most shells limit `local` to 1 var per line, contra bash.
  9. if [ "$KSH_VERSION" = 'Version JM 93t+ 2010-03-05' ]; then
  10. # The version of ksh93 that ships with many illumos systems does not
  11. # support the "local" extension. Print a message rather than fail in
  12. # subtle ways later on:
  13. echo 'rustup does not work with this ksh93 version; please try bash!' >&2
  14. exit 1
  15. fi
  16. set -u
  17. # If RUSTUP_UPDATE_ROOT is unset or empty, default it.
  18. RUSTUP_UPDATE_ROOT="${RUSTUP_UPDATE_ROOT:-https://static.rust-lang.org/rustup}"
  19. # NOTICE: If you change anything here, please make the same changes in setup_mode.rs
  20. usage() {
  21. cat <<EOF
  22. rustup-init 1.26.0 (577bf51ae 2023-04-05)
  23. The installer for rustup
  24. USAGE:
  25. rustup-init [OPTIONS]
  26. OPTIONS:
  27. -v, --verbose
  28. Enable verbose output
  29. -q, --quiet
  30. Disable progress output
  31. -y
  32. Disable confirmation prompt.
  33. --default-host <default-host>
  34. Choose a default host triple
  35. --default-toolchain <default-toolchain>
  36. Choose a default toolchain to install. Use 'none' to not install any toolchains at all
  37. --profile <profile>
  38. [default: default] [possible values: minimal, default, complete]
  39. -c, --component <components>...
  40. Component name to also install
  41. -t, --target <targets>...
  42. Target name to also install
  43. --no-update-default-toolchain
  44. Don't update any existing default toolchain after install
  45. --no-modify-path
  46. Don't configure the PATH environment variable
  47. -h, --help
  48. Print help information
  49. -V, --version
  50. Print version information
  51. EOF
  52. }
  53. main() {
  54. downloader --check
  55. need_cmd uname
  56. need_cmd mktemp
  57. need_cmd chmod
  58. need_cmd mkdir
  59. need_cmd rm
  60. need_cmd rmdir
  61. get_architecture || return 1
  62. local _arch="$RETVAL"
  63. assert_nz "$_arch" "arch"
  64. local _ext=""
  65. case "$_arch" in
  66. *windows*)
  67. _ext=".exe"
  68. ;;
  69. esac
  70. local _url="${RUSTUP_UPDATE_ROOT}/dist/${_arch}/rustup-init${_ext}"
  71. local _dir
  72. if ! _dir="$(ensure mktemp -d)"; then
  73. # Because the previous command ran in a subshell, we must manually
  74. # propagate exit status.
  75. exit 1
  76. fi
  77. local _file="${_dir}/rustup-init${_ext}"
  78. local _ansi_escapes_are_valid=false
  79. if [ -t 2 ]; then
  80. if [ "${TERM+set}" = 'set' ]; then
  81. case "$TERM" in
  82. xterm*|rxvt*|urxvt*|linux*|vt*)
  83. _ansi_escapes_are_valid=true
  84. ;;
  85. esac
  86. fi
  87. fi
  88. # check if we have to use /dev/tty to prompt the user
  89. local need_tty=yes
  90. for arg in "$@"; do
  91. case "$arg" in
  92. --help)
  93. usage
  94. exit 0
  95. ;;
  96. *)
  97. OPTIND=1
  98. if [ "${arg%%--*}" = "" ]; then
  99. # Long option (other than --help);
  100. # don't attempt to interpret it.
  101. continue
  102. fi
  103. while getopts :hy sub_arg "$arg"; do
  104. case "$sub_arg" in
  105. h)
  106. usage
  107. exit 0
  108. ;;
  109. y)
  110. # user wants to skip the prompt --
  111. # we don't need /dev/tty
  112. need_tty=no
  113. ;;
  114. *)
  115. ;;
  116. esac
  117. done
  118. ;;
  119. esac
  120. done
  121. if $_ansi_escapes_are_valid; then
  122. printf "\33[1minfo:\33[0m downloading installer\n" 1>&2
  123. else
  124. printf '%s\n' 'info: downloading installer' 1>&2
  125. fi
  126. ensure mkdir -p "$_dir"
  127. ensure downloader "$_url" "$_file" "$_arch"
  128. ensure chmod u+x "$_file"
  129. if [ ! -x "$_file" ]; then
  130. printf '%s\n' "Cannot execute $_file (likely because of mounting /tmp as noexec)." 1>&2
  131. printf '%s\n' "Please copy the file to a location where you can execute binaries and run ./rustup-init${_ext}." 1>&2
  132. exit 1
  133. fi
  134. if [ "$need_tty" = "yes" ] && [ ! -t 0 ]; then
  135. # The installer is going to want to ask for confirmation by
  136. # reading stdin. This script was piped into `sh` though and
  137. # doesn't have stdin to pass to its children. Instead we're going
  138. # to explicitly connect /dev/tty to the installer's stdin.
  139. if [ ! -t 1 ]; then
  140. err "Unable to run interactively. Run with -y to accept defaults, --help for additional options"
  141. fi
  142. ignore "$_file" "$@" < /dev/tty
  143. else
  144. ignore "$_file" "$@"
  145. fi
  146. local _retval=$?
  147. ignore rm "$_file"
  148. ignore rmdir "$_dir"
  149. return "$_retval"
  150. }
  151. check_proc() {
  152. # Check for /proc by looking for the /proc/self/exe link
  153. # This is only run on Linux
  154. if ! test -L /proc/self/exe ; then
  155. err "fatal: Unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc."
  156. fi
  157. }
  158. get_bitness() {
  159. need_cmd head
  160. # Architecture detection without dependencies beyond coreutils.
  161. # ELF files start out "\x7fELF", and the following byte is
  162. # 0x01 for 32-bit and
  163. # 0x02 for 64-bit.
  164. # The printf builtin on some shells like dash only supports octal
  165. # escape sequences, so we use those.
  166. local _current_exe_head
  167. _current_exe_head=$(head -c 5 /proc/self/exe )
  168. if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then
  169. echo 32
  170. elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then
  171. echo 64
  172. else
  173. err "unknown platform bitness"
  174. fi
  175. }
  176. is_host_amd64_elf() {
  177. need_cmd head
  178. need_cmd tail
  179. # ELF e_machine detection without dependencies beyond coreutils.
  180. # Two-byte field at offset 0x12 indicates the CPU,
  181. # but we're interested in it being 0x3E to indicate amd64, or not that.
  182. local _current_exe_machine
  183. _current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1)
  184. [ "$_current_exe_machine" = "$(printf '\076')" ]
  185. }
  186. get_endianness() {
  187. local cputype=$1
  188. local suffix_eb=$2
  189. local suffix_el=$3
  190. # detect endianness without od/hexdump, like get_bitness() does.
  191. need_cmd head
  192. need_cmd tail
  193. local _current_exe_endianness
  194. _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)"
  195. if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then
  196. echo "${cputype}${suffix_el}"
  197. elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then
  198. echo "${cputype}${suffix_eb}"
  199. else
  200. err "unknown platform endianness"
  201. fi
  202. }
  203. get_architecture() {
  204. local _ostype _cputype _bitness _arch _clibtype
  205. _ostype="$(uname -s)"
  206. _cputype="$(uname -m)"
  207. _clibtype="gnu"
  208. if [ "$_ostype" = Linux ]; then
  209. if [ "$(uname -o)" = Android ]; then
  210. _ostype=Android
  211. fi
  212. if ldd --version 2>&1 | grep -q 'musl'; then
  213. _clibtype="musl"
  214. fi
  215. fi
  216. if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then
  217. # Darwin `uname -m` lies
  218. if sysctl hw.optional.x86_64 | grep -q ': 1'; then
  219. _cputype=x86_64
  220. fi
  221. fi
  222. if [ "$_ostype" = SunOS ]; then
  223. # Both Solaris and illumos presently announce as "SunOS" in "uname -s"
  224. # so use "uname -o" to disambiguate. We use the full path to the
  225. # system uname in case the user has coreutils uname first in PATH,
  226. # which has historically sometimes printed the wrong value here.
  227. if [ "$(/usr/bin/uname -o)" = illumos ]; then
  228. _ostype=illumos
  229. fi
  230. # illumos systems have multi-arch userlands, and "uname -m" reports the
  231. # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86
  232. # systems. Check for the native (widest) instruction set on the
  233. # running kernel:
  234. if [ "$_cputype" = i86pc ]; then
  235. _cputype="$(isainfo -n)"
  236. fi
  237. fi
  238. case "$_ostype" in
  239. Android)
  240. _ostype=linux-android
  241. ;;
  242. Linux)
  243. check_proc
  244. _ostype=unknown-linux-$_clibtype
  245. _bitness=$(get_bitness)
  246. ;;
  247. FreeBSD)
  248. _ostype=unknown-freebsd
  249. ;;
  250. NetBSD)
  251. _ostype=unknown-netbsd
  252. ;;
  253. DragonFly)
  254. _ostype=unknown-dragonfly
  255. ;;
  256. Darwin)
  257. _ostype=apple-darwin
  258. ;;
  259. illumos)
  260. _ostype=unknown-illumos
  261. ;;
  262. MINGW* | MSYS* | CYGWIN* | Windows_NT)
  263. _ostype=pc-windows-gnu
  264. ;;
  265. *)
  266. err "unrecognized OS type: $_ostype"
  267. ;;
  268. esac
  269. case "$_cputype" in
  270. i386 | i486 | i686 | i786 | x86)
  271. _cputype=i686
  272. ;;
  273. xscale | arm)
  274. _cputype=arm
  275. if [ "$_ostype" = "linux-android" ]; then
  276. _ostype=linux-androideabi
  277. fi
  278. ;;
  279. armv6l)
  280. _cputype=arm
  281. if [ "$_ostype" = "linux-android" ]; then
  282. _ostype=linux-androideabi
  283. else
  284. _ostype="${_ostype}eabihf"
  285. fi
  286. ;;
  287. armv7l | armv8l)
  288. _cputype=armv7
  289. if [ "$_ostype" = "linux-android" ]; then
  290. _ostype=linux-androideabi
  291. else
  292. _ostype="${_ostype}eabihf"
  293. fi
  294. ;;
  295. aarch64 | arm64)
  296. _cputype=aarch64
  297. ;;
  298. x86_64 | x86-64 | x64 | amd64)
  299. _cputype=x86_64
  300. ;;
  301. mips)
  302. _cputype=$(get_endianness mips '' el)
  303. ;;
  304. mips64)
  305. if [ "$_bitness" -eq 64 ]; then
  306. # only n64 ABI is supported for now
  307. _ostype="${_ostype}abi64"
  308. _cputype=$(get_endianness mips64 '' el)
  309. fi
  310. ;;
  311. ppc)
  312. _cputype=powerpc
  313. ;;
  314. ppc64)
  315. _cputype=powerpc64
  316. ;;
  317. ppc64le)
  318. _cputype=powerpc64le
  319. ;;
  320. s390x)
  321. _cputype=s390x
  322. ;;
  323. riscv64)
  324. _cputype=riscv64gc
  325. ;;
  326. loongarch64)
  327. _cputype=loongarch64
  328. ;;
  329. *)
  330. err "unknown CPU type: $_cputype"
  331. esac
  332. # Detect 64-bit linux with 32-bit userland
  333. if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then
  334. case $_cputype in
  335. x86_64)
  336. if [ -n "${RUSTUP_CPUTYPE:-}" ]; then
  337. _cputype="$RUSTUP_CPUTYPE"
  338. else {
  339. # 32-bit executable for amd64 = x32
  340. if is_host_amd64_elf; then {
  341. echo "This host is running an x32 userland; as it stands, x32 support is poor," 1>&2
  342. echo "and there isn't a native toolchain -- you will have to install" 1>&2
  343. echo "multiarch compatibility with i686 and/or amd64, then select one" 1>&2
  344. echo "by re-running this script with the RUSTUP_CPUTYPE environment variable" 1>&2
  345. echo "set to i686 or x86_64, respectively." 1>&2
  346. echo 1>&2
  347. echo "You will be able to add an x32 target after installation by running" 1>&2
  348. echo " rustup target add x86_64-unknown-linux-gnux32" 1>&2
  349. exit 1
  350. }; else
  351. _cputype=i686
  352. fi
  353. }; fi
  354. ;;
  355. mips64)
  356. _cputype=$(get_endianness mips '' el)
  357. ;;
  358. powerpc64)
  359. _cputype=powerpc
  360. ;;
  361. aarch64)
  362. _cputype=armv7
  363. if [ "$_ostype" = "linux-android" ]; then
  364. _ostype=linux-androideabi
  365. else
  366. _ostype="${_ostype}eabihf"
  367. fi
  368. ;;
  369. riscv64gc)
  370. err "riscv64 with 32-bit userland unsupported"
  371. ;;
  372. esac
  373. fi
  374. # Detect armv7 but without the CPU features Rust needs in that build,
  375. # and fall back to arm.
  376. # See https://github.com/rust-lang/rustup.rs/issues/587.
  377. if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then
  378. if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then
  379. # At least one processor does not have NEON.
  380. _cputype=arm
  381. fi
  382. fi
  383. _arch="${_cputype}-${_ostype}"
  384. RETVAL="$_arch"
  385. }
  386. say() {
  387. printf 'rustup: %s\n' "$1"
  388. }
  389. err() {
  390. say "$1" >&2
  391. exit 1
  392. }
  393. need_cmd() {
  394. if ! check_cmd "$1"; then
  395. err "need '$1' (command not found)"
  396. fi
  397. }
  398. check_cmd() {
  399. command -v "$1" > /dev/null 2>&1
  400. }
  401. assert_nz() {
  402. if [ -z "$1" ]; then err "assert_nz $2"; fi
  403. }
  404. # Run a command that should never fail. If the command fails execution
  405. # will immediately terminate with an error showing the failing
  406. # command.
  407. ensure() {
  408. if ! "$@"; then err "command failed: $*"; fi
  409. }
  410. # This is just for indicating that commands' results are being
  411. # intentionally ignored. Usually, because it's being executed
  412. # as part of error handling.
  413. ignore() {
  414. "$@"
  415. }
  416. # This wraps curl or wget. Try curl first, if not installed,
  417. # use wget instead.
  418. downloader() {
  419. local _dld
  420. local _ciphersuites
  421. local _err
  422. local _status
  423. local _retry
  424. if check_cmd curl; then
  425. _dld=curl
  426. elif check_cmd wget; then
  427. _dld=wget
  428. else
  429. _dld='curl or wget' # to be used in error message of need_cmd
  430. fi
  431. if [ "$1" = --check ]; then
  432. need_cmd "$_dld"
  433. elif [ "$_dld" = curl ]; then
  434. check_curl_for_retry_support
  435. _retry="$RETVAL"
  436. get_ciphersuites_for_curl
  437. _ciphersuites="$RETVAL"
  438. if [ -n "$_ciphersuites" ]; then
  439. _err=$(curl $_retry --proto '=https' --tlsv1.2 --ciphers "$_ciphersuites" --silent --show-error --fail --location "$1" --output "$2" 2>&1)
  440. _status=$?
  441. else
  442. echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
  443. if ! check_help_for "$3" curl --proto --tlsv1.2; then
  444. echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
  445. _err=$(curl $_retry --silent --show-error --fail --location "$1" --output "$2" 2>&1)
  446. _status=$?
  447. else
  448. _err=$(curl $_retry --proto '=https' --tlsv1.2 --silent --show-error --fail --location "$1" --output "$2" 2>&1)
  449. _status=$?
  450. fi
  451. fi
  452. if [ -n "$_err" ]; then
  453. echo "$_err" >&2
  454. if echo "$_err" | grep -q 404$; then
  455. err "installer for platform '$3' not found, this may be unsupported"
  456. fi
  457. fi
  458. return $_status
  459. elif [ "$_dld" = wget ]; then
  460. if [ "$(wget -V 2>&1|head -2|tail -1|cut -f1 -d" ")" = "BusyBox" ]; then
  461. echo "Warning: using the BusyBox version of wget. Not enforcing strong cipher suites for TLS or TLS v1.2, this is potentially less secure"
  462. _err=$(wget "$1" -O "$2" 2>&1)
  463. _status=$?
  464. else
  465. get_ciphersuites_for_wget
  466. _ciphersuites="$RETVAL"
  467. if [ -n "$_ciphersuites" ]; then
  468. _err=$(wget --https-only --secure-protocol=TLSv1_2 --ciphers "$_ciphersuites" "$1" -O "$2" 2>&1)
  469. _status=$?
  470. else
  471. echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
  472. if ! check_help_for "$3" wget --https-only --secure-protocol; then
  473. echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
  474. _err=$(wget "$1" -O "$2" 2>&1)
  475. _status=$?
  476. else
  477. _err=$(wget --https-only --secure-protocol=TLSv1_2 "$1" -O "$2" 2>&1)
  478. _status=$?
  479. fi
  480. fi
  481. fi
  482. if [ -n "$_err" ]; then
  483. echo "$_err" >&2
  484. if echo "$_err" | grep -q ' 404 Not Found$'; then
  485. err "installer for platform '$3' not found, this may be unsupported"
  486. fi
  487. fi
  488. return $_status
  489. else
  490. err "Unknown downloader" # should not reach here
  491. fi
  492. }
  493. check_help_for() {
  494. local _arch
  495. local _cmd
  496. local _arg
  497. _arch="$1"
  498. shift
  499. _cmd="$1"
  500. shift
  501. local _category
  502. if "$_cmd" --help | grep -q 'For all options use the manual or "--help all".'; then
  503. _category="all"
  504. else
  505. _category=""
  506. fi
  507. case "$_arch" in
  508. *darwin*)
  509. if check_cmd sw_vers; then
  510. case $(sw_vers -productVersion) in
  511. 10.*)
  512. # If we're running on macOS, older than 10.13, then we always
  513. # fail to find these options to force fallback
  514. if [ "$(sw_vers -productVersion | cut -d. -f2)" -lt 13 ]; then
  515. # Older than 10.13
  516. echo "Warning: Detected macOS platform older than 10.13"
  517. return 1
  518. fi
  519. ;;
  520. 11.*)
  521. # We assume Big Sur will be OK for now
  522. ;;
  523. *)
  524. # Unknown product version, warn and continue
  525. echo "Warning: Detected unknown macOS major version: $(sw_vers -productVersion)"
  526. echo "Warning TLS capabilities detection may fail"
  527. ;;
  528. esac
  529. fi
  530. ;;
  531. esac
  532. for _arg in "$@"; do
  533. if ! "$_cmd" --help "$_category" | grep -q -- "$_arg"; then
  534. return 1
  535. fi
  536. done
  537. true # not strictly needed
  538. }
  539. # Check if curl supports the --retry flag, then pass it to the curl invocation.
  540. check_curl_for_retry_support() {
  541. local _retry_supported=""
  542. # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
  543. if check_help_for "notspecified" "curl" "--retry"; then
  544. _retry_supported="--retry 3"
  545. if check_help_for "notspecified" "curl" "--continue-at"; then
  546. # "-C -" tells curl to automatically find where to resume the download when retrying.
  547. _retry_supported="--retry 3 -C -"
  548. fi
  549. fi
  550. RETVAL="$_retry_supported"
  551. }
  552. # Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
  553. # if support by local tools is detected. Detection currently supports these curl backends:
  554. # GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
  555. get_ciphersuites_for_curl() {
  556. if [ -n "${RUSTUP_TLS_CIPHERSUITES-}" ]; then
  557. # user specified custom cipher suites, assume they know what they're doing
  558. RETVAL="$RUSTUP_TLS_CIPHERSUITES"
  559. return
  560. fi
  561. local _openssl_syntax="no"
  562. local _gnutls_syntax="no"
  563. local _backend_supported="yes"
  564. if curl -V | grep -q ' OpenSSL/'; then
  565. _openssl_syntax="yes"
  566. elif curl -V | grep -iq ' LibreSSL/'; then
  567. _openssl_syntax="yes"
  568. elif curl -V | grep -iq ' BoringSSL/'; then
  569. _openssl_syntax="yes"
  570. elif curl -V | grep -iq ' GnuTLS/'; then
  571. _gnutls_syntax="yes"
  572. else
  573. _backend_supported="no"
  574. fi
  575. local _args_supported="no"
  576. if [ "$_backend_supported" = "yes" ]; then
  577. # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
  578. if check_help_for "notspecified" "curl" "--tlsv1.2" "--ciphers" "--proto"; then
  579. _args_supported="yes"
  580. fi
  581. fi
  582. local _cs=""
  583. if [ "$_args_supported" = "yes" ]; then
  584. if [ "$_openssl_syntax" = "yes" ]; then
  585. _cs=$(get_strong_ciphersuites_for "openssl")
  586. elif [ "$_gnutls_syntax" = "yes" ]; then
  587. _cs=$(get_strong_ciphersuites_for "gnutls")
  588. fi
  589. fi
  590. RETVAL="$_cs"
  591. }
  592. # Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
  593. # if support by local tools is detected. Detection currently supports these wget backends:
  594. # GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
  595. get_ciphersuites_for_wget() {
  596. if [ -n "${RUSTUP_TLS_CIPHERSUITES-}" ]; then
  597. # user specified custom cipher suites, assume they know what they're doing
  598. RETVAL="$RUSTUP_TLS_CIPHERSUITES"
  599. return
  600. fi
  601. local _cs=""
  602. if wget -V | grep -q '\-DHAVE_LIBSSL'; then
  603. # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
  604. if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
  605. _cs=$(get_strong_ciphersuites_for "openssl")
  606. fi
  607. elif wget -V | grep -q '\-DHAVE_LIBGNUTLS'; then
  608. # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
  609. if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
  610. _cs=$(get_strong_ciphersuites_for "gnutls")
  611. fi
  612. fi
  613. RETVAL="$_cs"
  614. }
  615. # Return strong TLS 1.2-1.3 cipher suites in OpenSSL or GnuTLS syntax. TLS 1.2
  616. # excludes non-ECDHE and non-AEAD cipher suites. DHE is excluded due to bad
  617. # DH params often found on servers (see RFC 7919). Sequence matches or is
  618. # similar to Firefox 68 ESR with weak cipher suites disabled via about:config.
  619. # $1 must be openssl or gnutls.
  620. get_strong_ciphersuites_for() {
  621. if [ "$1" = "openssl" ]; then
  622. # OpenSSL is forgiving of unknown values, no problems with TLS 1.3 values on versions that don't support it yet.
  623. 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"
  624. elif [ "$1" = "gnutls" ]; then
  625. # GnuTLS isn't forgiving of unknown values, so this may require a GnuTLS version that supports TLS 1.3 even if wget doesn't.
  626. # Begin with SECURE128 (and higher) then remove/add to build cipher suites. Produces same 9 cipher suites as OpenSSL but in slightly different order.
  627. 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"
  628. fi
  629. }
  630. main "$@" || exit 1