1eb8dc403SDave Cobbley#!/bin/bash 2eb8dc403SDave Cobbley 3eb8dc403SDave Cobbley# oe-git-proxy is a simple tool to be via GIT_PROXY_COMMAND. It uses socat 4eb8dc403SDave Cobbley# to make SOCKS5 or HTTPS proxy connections. 5eb8dc403SDave Cobbley# It uses ALL_PROXY or all_proxy or http_proxy to determine the proxy server, 6eb8dc403SDave Cobbley# protocol, and port. 7eb8dc403SDave Cobbley# It uses NO_PROXY to skip using the proxy for a comma delimited list of 8eb8dc403SDave Cobbley# hosts, host globs (*.example.com), IPs, or CIDR masks (192.168.1.0/24). It 9eb8dc403SDave Cobbley# is known to work with both bash and dash shells. 10eb8dc403SDave Cobbley# 11eb8dc403SDave Cobbley# Example ALL_PROXY values: 12eb8dc403SDave Cobbley# ALL_PROXY=socks://socks.example.com:1080 13eb8dc403SDave Cobbley# ALL_PROXY=https://proxy.example.com:8080 14eb8dc403SDave Cobbley# 15eb8dc403SDave Cobbley# Copyright (c) 2013, Intel Corporation. 16c342db35SBrad Bishop# 17c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only 18eb8dc403SDave Cobbley# 19eb8dc403SDave Cobbley# AUTHORS 20eb8dc403SDave Cobbley# Darren Hart <dvhart@linux.intel.com> 21eb8dc403SDave Cobbley 22*a34c030eSBrad Bishop# disable pathname expansion, NO_PROXY fields could start with "*" or be it 23*a34c030eSBrad Bishopset -f 24*a34c030eSBrad Bishop 25eb8dc403SDave Cobbleyif [ $# -lt 2 -o "$1" = '--help' -o "$1" = '-h' ] ; then 26eb8dc403SDave Cobbley echo 'oe-git-proxy: error: the following arguments are required: host port' 27eb8dc403SDave Cobbley echo 'Usage: oe-git-proxy host port' 28eb8dc403SDave Cobbley echo '' 29eb8dc403SDave Cobbley echo 'OpenEmbedded git-proxy - a simple tool to be used via GIT_PROXY_COMMAND.' 30eb8dc403SDave Cobbley echo 'It uses socat to make SOCKS or HTTPS proxy connections.' 31eb8dc403SDave Cobbley echo 'It uses ALL_PROXY to determine the proxy server, protocol, and port.' 32eb8dc403SDave Cobbley echo 'It uses NO_PROXY to skip using the proxy for a comma delimited list' 33eb8dc403SDave Cobbley echo 'of hosts, host globs (*.example.com), IPs, or CIDR masks (192.168.1.0/24).' 34eb8dc403SDave Cobbley echo 'It is known to work with both bash and dash shells.runs native tools' 35eb8dc403SDave Cobbley echo '' 36eb8dc403SDave Cobbley echo 'arguments:' 37eb8dc403SDave Cobbley echo ' host proxy host to use' 38eb8dc403SDave Cobbley echo ' port proxy port to use' 39eb8dc403SDave Cobbley echo '' 40eb8dc403SDave Cobbley echo 'options:' 41eb8dc403SDave Cobbley echo ' -h, --help show this help message and exit' 42eb8dc403SDave Cobbley echo '' 43eb8dc403SDave Cobbley exit 2 44eb8dc403SDave Cobbleyfi 45eb8dc403SDave Cobbley 46eb8dc403SDave Cobbley# Locate the netcat binary 47*a34c030eSBrad Bishopif [ -z "$SOCAT" ]; then 48eb8dc403SDave Cobbley SOCAT=$(which socat 2>/dev/null) 49eb8dc403SDave Cobbley if [ $? -ne 0 ]; then 50eb8dc403SDave Cobbley echo "ERROR: socat binary not in PATH" 1>&2 51eb8dc403SDave Cobbley exit 1 52eb8dc403SDave Cobbley fi 53*a34c030eSBrad Bishopfi 54eb8dc403SDave CobbleyMETHOD="" 55eb8dc403SDave Cobbley 56eb8dc403SDave Cobbley# Test for a valid IPV4 quad with optional bitmask 57eb8dc403SDave Cobbleyvalid_ipv4() { 58eb8dc403SDave Cobbley echo $1 | egrep -q "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}(/(3[0-2]|[1-2]?[0-9]))?$" 59eb8dc403SDave Cobbley return $? 60eb8dc403SDave Cobbley} 61eb8dc403SDave Cobbley 62eb8dc403SDave Cobbley# Convert an IPV4 address into a 32bit integer 63eb8dc403SDave Cobbleyipv4_val() { 64eb8dc403SDave Cobbley IP="$1" 65eb8dc403SDave Cobbley SHIFT=24 66eb8dc403SDave Cobbley VAL=0 67*a34c030eSBrad Bishop for B in $( echo "$IP" | tr '.' ' ' ); do 68eb8dc403SDave Cobbley VAL=$(($VAL+$(($B<<$SHIFT)))) 69eb8dc403SDave Cobbley SHIFT=$(($SHIFT-8)) 70eb8dc403SDave Cobbley done 71eb8dc403SDave Cobbley echo "$VAL" 72eb8dc403SDave Cobbley} 73eb8dc403SDave Cobbley 74eb8dc403SDave Cobbley# Determine if two IPs are equivalent, or if the CIDR contains the IP 75eb8dc403SDave Cobbleymatch_ipv4() { 76eb8dc403SDave Cobbley CIDR=$1 77eb8dc403SDave Cobbley IP=$2 78eb8dc403SDave Cobbley 79eb8dc403SDave Cobbley if [ -z "${IP%%$CIDR}" ]; then 80eb8dc403SDave Cobbley return 0 81eb8dc403SDave Cobbley fi 82eb8dc403SDave Cobbley 83eb8dc403SDave Cobbley # Determine the mask bitlength 84eb8dc403SDave Cobbley BITS=${CIDR##*/} 85eb8dc403SDave Cobbley [ "$BITS" != "$CIDR" ] || BITS=32 86eb8dc403SDave Cobbley if [ -z "$BITS" ]; then 87eb8dc403SDave Cobbley return 1 88eb8dc403SDave Cobbley fi 89eb8dc403SDave Cobbley 90eb8dc403SDave Cobbley IPVAL=$(ipv4_val $IP) 91eb8dc403SDave Cobbley IP2VAL=$(ipv4_val ${CIDR%%/*}) 92eb8dc403SDave Cobbley 93eb8dc403SDave Cobbley # OR in the unmasked bits 94eb8dc403SDave Cobbley for i in $(seq 0 $((32-$BITS))); do 95eb8dc403SDave Cobbley IP2VAL=$(($IP2VAL|$((1<<$i)))) 96eb8dc403SDave Cobbley IPVAL=$(($IPVAL|$((1<<$i)))) 97eb8dc403SDave Cobbley done 98eb8dc403SDave Cobbley 99eb8dc403SDave Cobbley if [ $IPVAL -eq $IP2VAL ]; then 100eb8dc403SDave Cobbley return 0 101eb8dc403SDave Cobbley fi 102eb8dc403SDave Cobbley return 1 103eb8dc403SDave Cobbley} 104eb8dc403SDave Cobbley 105eb8dc403SDave Cobbley# Test to see if GLOB matches HOST 106eb8dc403SDave Cobbleymatch_host() { 107eb8dc403SDave Cobbley HOST=$1 108eb8dc403SDave Cobbley GLOB=$2 109eb8dc403SDave Cobbley 110*a34c030eSBrad Bishop if [ -z "${HOST%%*$GLOB}" ]; then 111eb8dc403SDave Cobbley return 0 112eb8dc403SDave Cobbley fi 113eb8dc403SDave Cobbley 114eb8dc403SDave Cobbley # Match by netmask 115eb8dc403SDave Cobbley if valid_ipv4 $GLOB; then 116eb8dc403SDave Cobbley for HOST_IP in $(getent ahostsv4 $HOST | grep ' STREAM ' | cut -d ' ' -f 1) ; do 117eb8dc403SDave Cobbley if valid_ipv4 $HOST_IP; then 118eb8dc403SDave Cobbley match_ipv4 $GLOB $HOST_IP 119eb8dc403SDave Cobbley if [ $? -eq 0 ]; then 120eb8dc403SDave Cobbley return 0 121eb8dc403SDave Cobbley fi 122eb8dc403SDave Cobbley fi 123eb8dc403SDave Cobbley done 124eb8dc403SDave Cobbley fi 125eb8dc403SDave Cobbley 126eb8dc403SDave Cobbley return 1 127eb8dc403SDave Cobbley} 128eb8dc403SDave Cobbley 129eb8dc403SDave Cobbley# If no proxy is set or needed, just connect directly 130eb8dc403SDave CobbleyMETHOD="TCP:$1:$2" 131eb8dc403SDave Cobbley 132eb8dc403SDave Cobbley[ -z "${ALL_PROXY}" ] && ALL_PROXY=$all_proxy 133eb8dc403SDave Cobbley[ -z "${ALL_PROXY}" ] && ALL_PROXY=$http_proxy 134eb8dc403SDave Cobbley 135eb8dc403SDave Cobbleyif [ -z "$ALL_PROXY" ]; then 136eb8dc403SDave Cobbley exec $SOCAT STDIO $METHOD 137eb8dc403SDave Cobbleyfi 138eb8dc403SDave Cobbley 139eb8dc403SDave Cobbley# Connect directly to hosts in NO_PROXY 140*a34c030eSBrad Bishopfor H in $( echo "$NO_PROXY" | tr ',' ' ' ); do 141*a34c030eSBrad Bishop if match_host $1 $H; then 142eb8dc403SDave Cobbley exec $SOCAT STDIO $METHOD 143eb8dc403SDave Cobbley fi 144eb8dc403SDave Cobbleydone 145eb8dc403SDave Cobbley 146eb8dc403SDave Cobbley# Proxy is necessary, determine protocol, server, and port 147eb8dc403SDave Cobbley# extract protocol 148eb8dc403SDave CobbleyPROTO=${ALL_PROXY%://*} 149eb8dc403SDave Cobbley# strip protocol:// from string 150eb8dc403SDave CobbleyALL_PROXY=${ALL_PROXY#*://} 151eb8dc403SDave Cobbley# extract host & port parts: 152eb8dc403SDave Cobbley# 1) drop username/password 153eb8dc403SDave CobbleyPROXY=${ALL_PROXY##*@} 154eb8dc403SDave Cobbley# 2) remove optional trailing /? 155eb8dc403SDave CobbleyPROXY=${PROXY%%/*} 156eb8dc403SDave Cobbley# 3) extract optional port 157eb8dc403SDave CobbleyPORT=${PROXY##*:} 158eb8dc403SDave Cobbleyif [ "$PORT" = "$PROXY" ]; then 159eb8dc403SDave Cobbley PORT="" 160eb8dc403SDave Cobbleyfi 161eb8dc403SDave Cobbley# 4) remove port 162eb8dc403SDave CobbleyPROXY=${PROXY%%:*} 163eb8dc403SDave Cobbley 164eb8dc403SDave Cobbley# extract username & password 165eb8dc403SDave CobbleyPROXYAUTH="${ALL_PROXY%@*}" 166eb8dc403SDave Cobbley[ "$PROXYAUTH" = "$ALL_PROXY" ] && PROXYAUTH= 167eb8dc403SDave Cobbley[ -n "${PROXYAUTH}" ] && PROXYAUTH=",proxyauth=${PROXYAUTH}" 168eb8dc403SDave Cobbley 169eb8dc403SDave Cobbleyif [ "$PROTO" = "socks" ] || [ "$PROTO" = "socks4a" ]; then 170eb8dc403SDave Cobbley if [ -z "$PORT" ]; then 171eb8dc403SDave Cobbley PORT="1080" 172eb8dc403SDave Cobbley fi 173eb8dc403SDave Cobbley METHOD="SOCKS4A:$PROXY:$1:$2,socksport=$PORT" 174eb8dc403SDave Cobbleyelif [ "$PROTO" = "socks4" ]; then 175eb8dc403SDave Cobbley if [ -z "$PORT" ]; then 176eb8dc403SDave Cobbley PORT="1080" 177eb8dc403SDave Cobbley fi 178eb8dc403SDave Cobbley METHOD="SOCKS4:$PROXY:$1:$2,socksport=$PORT" 179eb8dc403SDave Cobbleyelse 180eb8dc403SDave Cobbley # Assume PROXY (http, https, etc) 181eb8dc403SDave Cobbley if [ -z "$PORT" ]; then 182eb8dc403SDave Cobbley PORT="8080" 183eb8dc403SDave Cobbley fi 184eb8dc403SDave Cobbley METHOD="PROXY:$PROXY:$1:$2,proxyport=${PORT}${PROXYAUTH}" 185eb8dc403SDave Cobbleyfi 186eb8dc403SDave Cobbley 187eb8dc403SDave Cobbleyexec $SOCAT STDIO "$METHOD" 188