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.

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