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.

203 lines
6.2 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 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. if [ -n "$CISCO_SPLIT_DNS" ] && [ -d "/tmp/dnsmasq.d/" ];then
  70. SDNS=`echo $CISCO_SPLIT_DNS|sed 's/,/\n/g'`
  71. DNSMASQ_FILE="/tmp/dnsmasq.d/openconnect.$TUNDEV"
  72. rm -f $DNSMASQ_FILE
  73. echo "$SDNS" | while read i; do
  74. if [ -n "$INTERNAL_IP4_DNS" ];then
  75. for dns in "$INTERNAL_IP4_DNS";do
  76. echo "server=/$i/$dns" >> $DNSMASQ_FILE
  77. done
  78. fi
  79. if [ -n "$INTERNAL_IP6_DNS" ];then
  80. for dns in "$INTERNAL_IP6_DNS";do
  81. echo "server=/$i/$dns" >> $DNSMASQ_FILE
  82. done
  83. fi
  84. echo "rebind-domain-ok=$i" >> $DNSMASQ_FILE
  85. done
  86. /etc/init.d/dnsmasq restart
  87. else
  88. if [ -n "$INTERNAL_IP4_DNS" ];then
  89. for dns in "$INTERNAL_IP4_DNS";do
  90. proto_add_dns_server "$dns"
  91. done
  92. fi
  93. if [ -n "$INTERNAL_IP6_DNS" ];then
  94. for dns in "$INTERNAL_IP6_DNS";do
  95. proto_add_dns_server "$dns"
  96. done
  97. fi
  98. [ -n "$CISCO_DEF_DOMAIN" ] && proto_add_dns_search "$CISCO_DEF_DOMAIN"
  99. fi
  100. if [ -n "$CISCO_SPLIT_INC" ]; then
  101. i=0
  102. while [ $i -lt $CISCO_SPLIT_INC ] ; do
  103. eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
  104. eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
  105. eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
  106. if [ $NETWORK != "0.0.0.0" ]; then
  107. proto_add_ipv4_route "$NETWORK" "$NETMASKLEN"
  108. else
  109. proto_add_ipv4_route "0.0.0.0" 0
  110. fi
  111. i=$(($i + 1))
  112. done
  113. elif [ -n "$INTERNAL_IP4_ADDRESS" ]; then
  114. proto_add_ipv4_route "0.0.0.0" 0
  115. fi
  116. if [ -n "$CISCO_IPV6_SPLIT_INC" ]; then
  117. i=0
  118. while [ $i -lt $CISCO_IPV6_SPLIT_INC ] ; do
  119. eval NETWORK="\${CISCO_IPV6_SPLIT_INC_${i}_ADDR}"
  120. eval NETMASKLEN="\${CISCO_IPV6_SPLIT_INC_${i}_MASKLEN}"
  121. if [ $NETMASKLEN -lt 128 ]; then
  122. proto_add_ipv6_route "$NETWORK" "$NETMASKLEN"
  123. else
  124. proto_add_ipv6_route "::0" 0
  125. fi
  126. i=$(($i + 1))
  127. done
  128. elif [ -n "$INTERNAL_IP6_NETMASK" -o -n "$INTERNAL_IP6_ADDRESS" ]; then
  129. proto_add_ipv6_route "::0" 0
  130. fi
  131. proto_send_update "$INTERFACE"
  132. }
  133. do_disconnect() {
  134. rm -f "/tmp/dnsmasq.d/openconnect.$TUNDEV"
  135. proto_init_update "$TUNDEV" 0
  136. proto_send_update "$INTERFACE"
  137. }
  138. #### Hooks
  139. run_hooks() {
  140. HOOK="$1"
  141. if [ -d ${HOOKS_DIR}/${HOOK}.d ]; then
  142. for script in ${HOOKS_DIR}/${HOOK}.d/* ; do
  143. [ -f $script ] && . $script
  144. done
  145. fi
  146. }
  147. #### Main
  148. if [ -z "$reason" ]; then
  149. logger -t openconnect "this script must be called from vpnc" 1>&2
  150. exit 1
  151. fi
  152. if [ -z "$INTERFACE" ]; then
  153. logger -t openconnect "this script must be called for an active interface"
  154. exit 1
  155. fi
  156. . /lib/netifd/netifd-proto.sh
  157. case "$reason" in
  158. pre-init)
  159. run_hooks pre-init
  160. ;;
  161. connect)
  162. run_hooks connect
  163. do_connect
  164. run_hooks post-connect
  165. ;;
  166. disconnect)
  167. run_hooks disconnect
  168. do_disconnect
  169. run_hooks post-disconnect
  170. ;;
  171. reconnect)
  172. run_hooks reconnect
  173. ;;
  174. *)
  175. logger -t openconnect "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
  176. exit 1
  177. ;;
  178. esac
  179. exit 0