You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
6.7 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. #!/bin/sh
  2. # List of parameters passed through environment
  3. #* reason -- why this script was called, one of: pre-init connect disconnect
  4. #* VPNGATEWAY -- vpn gateway address (always present)
  5. #* TUNDEV -- tunnel device (always present)
  6. #* INTERNAL_IP4_ADDRESS -- address (always present)
  7. #* INTERNAL_IP4_MTU -- mtu (often unset)
  8. #* INTERNAL_IP4_NETMASK -- netmask (often unset)
  9. #* INTERNAL_IP4_NETMASKLEN -- netmask length (often unset)
  10. #* INTERNAL_IP4_NETADDR -- address of network (only present if netmask is set)
  11. #* INTERNAL_IP4_DNS -- list of dns servers
  12. #* INTERNAL_IP4_NBNS -- list of wins servers
  13. #* INTERNAL_IP6_ADDRESS -- IPv6 address
  14. #* INTERNAL_IP6_NETMASK -- IPv6 netmask
  15. #* INTERNAL_IP6_DNS -- IPv6 list of dns servers
  16. #* CISCO_DEF_DOMAIN -- default domain name
  17. #* CISCO_BANNER -- banner from server
  18. #* CISCO_SPLIT_INC -- number of networks in split-network-list
  19. #* CISCO_SPLIT_INC_%d_ADDR -- network address
  20. #* CISCO_SPLIT_INC_%d_MASK -- subnet mask (for example: 255.255.255.0)
  21. #* CISCO_SPLIT_INC_%d_MASKLEN -- subnet masklen (for example: 24)
  22. #* CISCO_SPLIT_INC_%d_PROTOCOL -- protocol (often just 0)
  23. #* CISCO_SPLIT_INC_%d_SPORT -- source port (often just 0)
  24. #* CISCO_SPLIT_INC_%d_DPORT -- destination port (often just 0)
  25. #* CISCO_IPV6_SPLIT_INC -- number of networks in IPv6 split-network-list
  26. #* CISCO_IPV6_SPLIT_INC_%d_ADDR -- IPv6 network address
  27. #* CISCO_IPV6_SPLIT_INC_$%d_MASKLEN -- IPv6 subnet masklen
  28. HOOKS_DIR=/etc/openconnect
  29. # FIXMEs:
  30. # Section A: route handling
  31. # 1) The 3 values CISCO_SPLIT_INC_%d_PROTOCOL/SPORT/DPORT are currently being ignored
  32. # In order to use them, we'll probably need os specific solutions
  33. # * Linux: iptables -t mangle -I PREROUTING <conditions> -j ROUTE --oif $TUNDEV
  34. # This would be an *alternative* to changing the routes (and thus 2) and 3)
  35. # shouldn't be relevant at all)
  36. # 2) There are two different functions to set routes: generic routes and the
  37. # default route. Why isn't the defaultroute handled via the generic route case?
  38. # 3) In the split tunnel case, all routes but the default route might get replaced
  39. # without getting restored later. We should explicitely check and save them just
  40. # like the defaultroute
  41. # 4) Replies to a dhcp-server should never be sent into the tunnel
  42. # Section B: Split DNS handling
  43. # 1) We parse CISCO_SPLIT_DNS and use dnsmasq to set it
  44. do_connect() {
  45. if [ -n "$CISCO_BANNER" ]; then
  46. logger -t openconnect "Connect Banner:"
  47. echo "$CISCO_BANNER" | while read LINE ; do logger -t openconnect "|" "$LINE" ; done
  48. fi
  49. proto_init_update "$TUNDEV" 1
  50. if [ -n "$INTERNAL_IP4_MTU" ]; then
  51. MTU=$INTERNAL_IP4_MTU
  52. fi
  53. if [ -z "$MTU" ]; then
  54. MTU=1412
  55. fi
  56. proto_add_ipv4_address "$INTERNAL_IP4_ADDRESS" 32 "" "$INTERNAL_IP4_ADDRESS"
  57. if [ -n "$INTERNAL_IP4_NETMASKLEN" ]; then
  58. proto_add_ipv4_route "$INTERNAL_IP4_NETADDR" "$INTERNAL_IP4_NETMASKLEN"
  59. fi
  60. # If the netmask is provided, it contains the address _and_ netmask
  61. if [ -n "$INTERNAL_IP6_ADDRESS" ] && [ -z "$INTERNAL_IP6_NETMASK" ]; then
  62. INTERNAL_IP6_NETMASK="$INTERNAL_IP6_ADDRESS/128"
  63. fi
  64. if [ -n "$INTERNAL_IP6_NETMASK" ]; then
  65. addr="${INTERNAL_IP6_NETMASK%%/*}"
  66. mask="${INTERNAL_IP6_NETMASK##*/}"
  67. [[ "$addr" != "$mask" ]] && proto_add_ipv6_address "$addr" "$mask"
  68. fi
  69. DNSMASQ_FILE="/tmp/dnsmasq.d/openconnect.$TUNDEV"
  70. LOCAL_DOMAIN=$(uci get dhcp.@dnsmasq[0].domain)
  71. rm -f $DNSMASQ_FILE
  72. if [ -n "$CISCO_SPLIT_DNS" ] && [ -d "/tmp/dnsmasq.d/" ];then
  73. SDNS=`echo $CISCO_SPLIT_DNS|sed 's/,/\n/g'`
  74. echo "$SDNS" | while read i; do
  75. if [ "$i" = "$LOCAL_DOMAIN" ];then
  76. continue
  77. fi
  78. if [ -n "$INTERNAL_IP4_DNS" ];then
  79. for dns in $INTERNAL_IP4_DNS;do
  80. echo "server=/$i/$dns" >> $DNSMASQ_FILE
  81. done
  82. fi
  83. if [ -n "$INTERNAL_IP6_DNS" ];then
  84. for dns in $INTERNAL_IP6_DNS;do
  85. echo "server=/$i/$dns" >> $DNSMASQ_FILE
  86. done
  87. fi
  88. echo "rebind-domain-ok=$i" >> $DNSMASQ_FILE
  89. done
  90. /etc/init.d/dnsmasq restart
  91. else
  92. if [ -n "$INTERNAL_IP4_DNS" ];then
  93. for dns in $INTERNAL_IP4_DNS;do
  94. proto_add_dns_server "$dns"
  95. done
  96. fi
  97. if [ -n "$INTERNAL_IP6_DNS" ];then
  98. for dns in $INTERNAL_IP6_DNS;do
  99. proto_add_dns_server "$dns"
  100. done
  101. fi
  102. if [ -n "$CISCO_DEF_DOMAIN" ] && [ "$CISCO_DEF_DOMAIN" != "$LOCAL_DOMAIN" ];then
  103. if [ -n "$INTERNAL_IP4_DNS" ];then
  104. for dns in $INTERNAL_IP4_DNS;do
  105. echo "server=/$CISCO_DEF_DOMAIN/$dns" >> $DNSMASQ_FILE
  106. done
  107. fi
  108. if [ -n "$INTERNAL_IP6_DNS" ];then
  109. for dns in $INTERNAL_IP6_DNS;do
  110. echo "server=/$CISCO_DEF_DOMAIN/$dns" >> $DNSMASQ_FILE
  111. done
  112. fi
  113. proto_add_dns_search "$CISCO_DEF_DOMAIN"
  114. fi
  115. fi
  116. if [ -n "$CISCO_SPLIT_INC" ]; then
  117. i=0
  118. while [ $i -lt $CISCO_SPLIT_INC ] ; do
  119. eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
  120. eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
  121. eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
  122. if [ $NETWORK != "0.0.0.0" ]; then
  123. proto_add_ipv4_route "$NETWORK" "$NETMASKLEN"
  124. else
  125. proto_add_ipv4_route "0.0.0.0" 0
  126. fi
  127. i=$(($i + 1))
  128. done
  129. elif [ -n "$INTERNAL_IP4_ADDRESS" ]; then
  130. proto_add_ipv4_route "0.0.0.0" 0
  131. fi
  132. if [ -n "$CISCO_IPV6_SPLIT_INC" ]; then
  133. i=0
  134. while [ $i -lt $CISCO_IPV6_SPLIT_INC ] ; do
  135. eval NETWORK="\${CISCO_IPV6_SPLIT_INC_${i}_ADDR}"
  136. eval NETMASKLEN="\${CISCO_IPV6_SPLIT_INC_${i}_MASKLEN}"
  137. if [ $NETMASKLEN -lt 128 ]; then
  138. proto_add_ipv6_route "$NETWORK" "$NETMASKLEN"
  139. else
  140. proto_add_ipv6_route "::0" 0
  141. fi
  142. i=$(($i + 1))
  143. done
  144. elif [ -n "$INTERNAL_IP6_NETMASK" -o -n "$INTERNAL_IP6_ADDRESS" ]; then
  145. proto_add_ipv6_route "::0" 0
  146. fi
  147. proto_send_update "$INTERFACE"
  148. }
  149. do_disconnect() {
  150. rm -f "/tmp/dnsmasq.d/openconnect.$TUNDEV"
  151. proto_init_update "$TUNDEV" 0
  152. proto_send_update "$INTERFACE"
  153. }
  154. #### Hooks
  155. run_hooks() {
  156. HOOK="$1"
  157. if [ -d ${HOOKS_DIR}/${HOOK}.d ]; then
  158. for script in ${HOOKS_DIR}/${HOOK}.d/* ; do
  159. [ -f $script ] && . $script
  160. done
  161. fi
  162. }
  163. #### Main
  164. if [ -z "$reason" ]; then
  165. logger -t openconnect "this script must be called from vpnc" 1>&2
  166. exit 1
  167. fi
  168. if [ -z "$INTERFACE" ]; then
  169. logger -t openconnect "this script must be called for an active interface"
  170. exit 1
  171. fi
  172. . /lib/netifd/netifd-proto.sh
  173. case "$reason" in
  174. pre-init)
  175. run_hooks pre-init
  176. ;;
  177. connect)
  178. run_hooks connect
  179. do_connect
  180. run_hooks post-connect
  181. ;;
  182. disconnect)
  183. run_hooks disconnect
  184. do_disconnect
  185. run_hooks post-disconnect
  186. ;;
  187. reconnect)
  188. run_hooks reconnect
  189. ;;
  190. attempt-reconnect)
  191. run_hooks attempt-reconnect
  192. ;;
  193. *)
  194. logger -t openconnect "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
  195. exit 1
  196. ;;
  197. esac
  198. exit 0