xref: /openbmc/openbmc/poky/scripts/oe-git-proxy (revision a34c030e)
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