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