#!/bin/bash # -*- mode: sh; tab-width: 8; coding: utf-8-unix -*- # must not use stdout prog=$( basename $0 .bash ) PREFIX=/usr/local ROLE=proxy prog=scurl umask 022 RETRIES=2 SSL_VER=3 . /usr/local/bin/proxy_ping_lib.bash [ -f /usr/local/bin/proxy_curl_lib.bash ] && \ . /usr/local/bin/proxy_curl_lib.bash if ! grep -q "^wlan[1-9][ ]00000000" /proc/net/route ; then WARN $prog we are not connected >&2 exit -1 fi usage="curls with some wget options Usage: $prog options -- curl-options Options: -P, --directory-prefix -X, --force-directories create directories to download to -C, --cacert CA certs in .pem -M, --mode proxy_ping_mode -S, --ssl ssl version 2=tls1.2 3=tls1.3 -Y, --ciphers comma sep list of ciphers -Q, --quiet --silent --show-error -h, --help display this help and exit " if [[ $? -ne 0 ]]; then echo "$usage" exit 2 fi declare -a LARGS # --location is required to follow redirects # im not sure about --http2 LARGS+=( --remote-time --location --max-redirs 10 --continue-at - ) LARGS+=( --retry-delay 10 --show-error --fail ) # --proto-redir https --proto =https is required to prevent protocol downgrades LARGS+=( --proto-redir https --proto-default https --proto =https ) [ -z "$MODE" ] && MODE=$( /usr/local/bin/proxy_ping_lib.bash proxy_ping_mode ) [ -z "$socks_proxy" ] && . /usr/local/bin/proxy_export.bash SSL_LIB=openssl # nss if [ -x $PREFIX/bin/curl.bash ] ; then EXE=$PREFIX/bin/curl.bash elif which scurl ; then EXE=`which scurl` else EXE=curl fi SHORT=M:QP:XC:F:hS: LONG=mode:,quiet,directory-prefix:,force-directories,cacert,ca-cert:,help,ssl: #? export POSIXLY_CORRECT=1 PARSED=$(getopt --options $SHORT --longoptions $LONG --name "$prog" -- "$@") eval set -- "$PARSED" P="$PWD" X="0" # echo DEBUG: WD=$WD rest=$* LOGF=/tmp/$prog$$.err SSL_CIPHERS="" while true; do case "$1" in -P|--directory-prefix) shift P="$1" shift # echo DEBUG: P=$WD rest=$* ;; -X|--force-directories) X=1 shift ;; -S|--ssl) shift SSL_VER="$1" shift ;; -Y|--ciphers) shift SSL_CIPHERS="$1" shift ;; -C|--cacert|-Z|--ca-cert) shift CA_CERT="$1" shift ;; -M|--mode) shift MODE="$1" shift ;; -Q|--quiet) shift LARGS="$LARGS --silent --show-error" ;; -h|--help) echo USAGE: "$usage" exit 0 ;; --) shift break ;; *) # echo ERROR: unhandled arguments $* - use -- after -P $PWD or -X ; exit 3 break ;; esac done [ "$SSL_VER" -ge 2 -a "$SSL_VER" -le 3 ] || { ERROR "SSL_VER $SSL_VER" ; exit 6 ; } LARGS+=( --tlsv1.$SSL_VER ) if [ -n "$SSL_CIPHERS" -a "$SSL_VER" = 2 ] ; then [ $SSL_LIB = openssl ] && \ SSL_CIPHERS="ECDHE-RSA-AES256-SHA" # ECDHE-RSA-AES256-GCM-SHA384 [ $SSL_LIB = nss ] && \ SSL_CIPHERS="ecdhe_rsa_aes_256_sha" fi if [ -n "$SSL_CIPHERS" -a "$SSL_VER" = 3 ] ; then [ $SSL_LIB = openssl ] && \ SSL_CIPHERS="TLS_AES_256_GCM_SHA384" # TLS_CHACHA20_POLY1305_SHA256 [ $SSL_LIB = nss ] && \ SSL_CIPHERS="aes_256_gcm_sha_384" fi [ -n "$SSL_CIPHERS" ] && LARGS+=( --ciphers "$SSL_CIPHERS" ) if [ "$MODE" = tor -o "$MODE" = selektor -o "$MODE" = whonix ] && \ netstat -nle4 | grep -q 127.0.0.1:53 ; then LARGS+=( --dns-ipv4-addr 127.0.0.1 --dns-servers 127.0.0.1 ) elif [ "$MODE" = whonix ] && ifconfig virbr1 | grep -q 10.0.2.2 ; then LARGS+=( --dns-ipv4-addr 10.0.2.15:9053 --dns-servers 10.0.2.15:9053 ) else debug 127.0.0.1:53 not running MODE=$MODE fi if ! uname -a | grep -q 'Devuan\|Debian' ; then if [ -f $HOME/.local/ ] ; then [ -f $HOME/.local/alt.svc ] || touch $HOME/.local/alt.svc LARGS+=( --alt-svc $HOME/.local/alt.svc ) # #define CURLALTSVC_H2 (1<<4) fi export CURLOPT_ALTSVC_CTRL=16 fi declare -a RARGS RARGS=("$@") DBUG "$#" "${RARGS[*]}" >&2 i=0 while [ $i -le $RETRIES ] ; do # assumes one URL if [ "${#RARGS[@]}" -eq 1 ] ; then the_url=`sed -e 's@http://@https://@g' -e 's@https*://distfiles.gentoo.org@https://gentoo.osuosl.org@g' -e 's@https*://gentoo.osuosl.org@https://mirror.leaseweb.com/gentoo@g' <<< "${RARGS[*]}"` else the_url=`sed -e 's@http://@https://@' -e 's@https*://distfiles.gentoo.org@https://gentoo.osuosl.org@g' -e 's@https*://gentoo.osuosl.org@https://mirror.leaseweb.com/gentoo@g' <<< "${RARGS[-1]}"` fi RARGS[-1]="$the_url" site=`sed -e 's@https*://@@g' -e 's@/.*@@' <<< $the_url` i=`expr $i + 1` if [ "$X" = 1 ] ; then rel_file=$( sed -e 's@^file://*@@' -e 's@^https*://*@@' -e 's@[&?#].*@@' <<< $the_url ) rel_dir=$( sed -e 's@/$@@' <<< $rel_file ) rel_dir=$( sed -e 's@/[^/]*$@@' <<< $rel_dir ) [ -d "$P/$rel_dir" ] || mkdir -p "$P/$rel_dir" output=`sed -e 's/[!:?#]/_/g' <<< "$P/$rel_file"` LARGS+=( --output "$output" --create-dirs ) fi DBUG $EXE "${LARGS[@]}" "${RARGS[@]}" >&2 echo $EXE "${LARGS[@]}" "${RARGS[@]}" > $LOGF $EXE "${LARGS[@]}" "${RARGS[@]}" >> $LOGF 2>&1 retval=$? if [ "$retval" -eq 22 ] || \ tail -4 $LOGF | grep -q 'The requested URL returned error:'; then # on 22 - change to HTTP code code=`tail -4 $LOGF | grep 'The requested URL returned error:' | sed -e 's/.*returned error: //' -e 's/ *$//'` if [ "$code" = 416 ] ; then INFO "$prog retval=$retval code=$code ${HTTP_RESPONSE[416]} $the_url = $LOGF" >&2 retval=$code elif [ "$code" = 429 ] ; then ERROR "$prog retval=$retval code=$code ${HTTP_RESPONSE[$code]} $the_url = $LOGF" >&2 retval=$code exit $retval elif [ -n "$code" ] && [ "$code" -ge 400 ] ; then # 403 Cloudflare ERROR "$prog retval=$retval code=$code ${HTTP_RESPONSE[$code]} $the_url = $LOGF" >&2 retval=$code elif [ -n "$code" ] && [ "$code" -lt 400 ] ; then INFO "$prog retval=$retval code=$code ${HTTP_RESPONSE[$code]} $the_url = $LOGF" >&2 else WARN "$prog retval=$retval \"$code\" $the_url = $LOGF" >&2 fi elif [ "$retval" = 35 ] ; then # 35 CURLE_SSL_CONNECT_ERROR ERROR "$prog retval=$retval CURLE_SSL_CONNECT_ERROR $the_url = $LOGF" >&2 # feedback to scurl_urls.sh NOTLSV3+=( $site ) elif [ "$retval" = 1 ] ; then # retval=1 CURLE=CURLE_UNSUPPORTED_PROTOCOL - seems to be a transient error WARN "$prog retval=$retval CURLE=${CURLE[$retval]} $the_url = $LOGF" >&2 continue elif [ "$retval" = 92 ] ; then # curl: (92) HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2) WARN "$prog retval=$retval CURLE=${CURLE[$retval]} $the_url = $LOGF" >&2 continue elif [ "$retval" -ne 0 ] ; then # curl: (3) URL using bad/illegal format or missing URL - worked WARN "$prog retval=$retval CURLE=${CURLE[$retval]} $the_url = $LOGF" >&2 elif tail -3 $LOGF | grep -q "HTTP code 504 from proxy after CONNECT" ; then WARN "$prog HTTP code 504 from proxy after CONNECT $the_url = $LOGF" >&2 continue elif tail -3 $LOGF | grep -q "503 - Forwarding failure" ; then WARN "$prog 503 - Forwarding failure $the_url = $LOGF" >&2 continue else INFO "$prog $output = $LOGF" >&2 # rm -f $LOGF fi break # "$P/$rel_file" # if [ $retval -gt 0 ] ; then # The requested URL returned error: 416 # if [ $retval = 22 ] && [ "$code" = 416 ] && [ -f "$P/$rel_file" ] ; then # fi done exit $retval