oe-git-proxy 3.1 KB

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