blob: 48734556a148188094acf139d3f51167e6e4eeba [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/bin/bash
2
3# oe-git-proxy is a simple tool to be via GIT_PROXY_COMMAND. It uses socat
4# to make SOCKS5 or HTTPS proxy connections. It uses ALL_PROXY to determine the
5# proxy server, protocol, and port. It uses NO_PROXY to skip using the proxy for
6# a comma delimited list of hosts, host globs (*.example.com), IPs, or CIDR
7# masks (192.168.1.0/24). It is known to work with both bash and dash shells.
8#
9# Example ALL_PROXY values:
10# ALL_PROXY=socks://socks.example.com:1080
11# ALL_PROXY=https://proxy.example.com:8080
12#
13# Copyright (c) 2013, Intel Corporation.
14# All rights reserved.
15#
16# AUTHORS
17# Darren Hart <dvhart@linux.intel.com>
18
19# Locate the netcat binary
20SOCAT=$(which socat 2>/dev/null)
21if [ $? -ne 0 ]; then
22 echo "ERROR: socat binary not in PATH" 1>&2
23 exit 1
24fi
25METHOD=""
26
27# Test for a valid IPV4 quad with optional bitmask
28valid_ipv4() {
29 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]))?$"
30 return $?
31}
32
33# Convert an IPV4 address into a 32bit integer
34ipv4_val() {
35 IP="$1"
36 SHIFT=24
37 VAL=0
38 for B in ${IP//./ }; do
39 VAL=$(($VAL+$(($B<<$SHIFT))))
40 SHIFT=$(($SHIFT-8))
41 done
42 echo "$VAL"
43}
44
45# Determine if two IPs are equivalent, or if the CIDR contains the IP
46match_ipv4() {
47 CIDR=$1
48 IP=$2
49
50 if [ -z "${IP%%$CIDR}" ]; then
51 return 0
52 fi
53
54 # Determine the mask bitlength
55 BITS=${CIDR##*/}
56 if [ -z "$BITS" ]; then
57 return 1
58 fi
59
60 IPVAL=$(ipv4_val $IP)
61 IP2VAL=$(ipv4_val ${CIDR%%/*})
62
63 # OR in the unmasked bits
64 for i in $(seq 0 $((32-$BITS))); do
65 IP2VAL=$(($IP2VAL|$((1<<$i))))
66 IPVAL=$(($IPVAL|$((1<<$i))))
67 done
68
69 if [ $IPVAL -eq $IP2VAL ]; then
70 return 0
71 fi
72 return 1
73}
74
75# Test to see if GLOB matches HOST
76match_host() {
77 HOST=$1
78 GLOB=$2
79
80 if [ -z "${HOST%%$GLOB}" ]; then
81 return 0
82 fi
83
84 # Match by netmask
85 if valid_ipv4 $GLOB; then
86 HOST_IP=$(gethostip -d $HOST)
87 if valid_ipv4 $HOST_IP; then
88 match_ipv4 $GLOB $HOST_IP
89 if [ $? -eq 0 ]; then
90 return 0
91 fi
92 fi
93 fi
94
95 return 1
96}
97
98# If no proxy is set or needed, just connect directly
99METHOD="TCP:$1:$2"
100
101if [ -z "$ALL_PROXY" ]; then
102 exec $SOCAT STDIO $METHOD
103fi
104
105# Connect directly to hosts in NO_PROXY
106for H in ${NO_PROXY//,/ }; do
107 if match_host $1 $H; then
108 exec $SOCAT STDIO $METHOD
109 fi
110done
111
112# Proxy is necessary, determine protocol, server, and port
113PROTO=$(echo $ALL_PROXY | sed -e 's/\([^:]*\):\/\/.*/\1/')
114PROXY=$(echo $ALL_PROXY | sed -e 's/.*:\/\/\([^:]*\).*/\1/')
115PORT=$(echo $ALL_PROXY | sed -e 's/.*:\([0-9]*\)\/?$/\1/')
116if [ "$PORT" = "$ALL_PROXY" ]; then
117 PORT=""
118fi
119
120if [ "$PROTO" = "socks" ]; then
121 if [ -z "$PORT" ]; then
122 PORT="1080"
123 fi
124 METHOD="SOCKS4A:$PROXY:$1:$2,socksport=$PORT"
125else
126 # Assume PROXY (http, https, etc)
127 if [ -z "$PORT" ]; then
128 PORT="8080"
129 fi
130 METHOD="PROXY:$PROXY:$1:$2,proxyport=$PORT"
131fi
132
133exec $SOCAT STDIO $METHOD