Advertisement
Guest User

/etc/vpnc/vpnc-script

a guest
Mar 12th, 2019
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.47 KB | None | 0 0
  1. #!/bin/sh
  2. #
  3. # Originally part of vpnc source code:
  4. # © 2005-2012 Maurice Massar, Jörg Mayer, Antonio Borneo et al.
  5. # © 2009-2012 David Woodhouse <dwmw2@infradead.org>
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. #
  21. ################
  22. #
  23. # List of parameters passed through environment
  24. #* reason -- why this script was called, one of: pre-init connect disconnect reconnect
  25. #* VPNGATEWAY -- vpn gateway address (always present)
  26. #* TUNDEV -- tunnel device (always present)
  27. #* INTERNAL_IP4_ADDRESS -- address (always present)
  28. #* INTERNAL_IP4_MTU -- mtu (often unset)
  29. #* INTERNAL_IP4_NETMASK -- netmask (often unset)
  30. #* INTERNAL_IP4_NETMASKLEN -- netmask length (often unset)
  31. #* INTERNAL_IP4_NETADDR -- address of network (only present if netmask is set)
  32. #* INTERNAL_IP4_DNS -- list of dns servers
  33. #* INTERNAL_IP4_NBNS -- list of wins servers
  34. #* INTERNAL_IP6_ADDRESS -- IPv6 address
  35. #* INTERNAL_IP6_NETMASK -- IPv6 netmask
  36. #* INTERNAL_IP6_DNS -- IPv6 list of dns servers
  37. #* CISCO_DEF_DOMAIN -- default domain name
  38. #* CISCO_BANNER -- banner from server
  39. #* CISCO_SPLIT_INC -- number of networks in split-network-list
  40. #* CISCO_SPLIT_INC_%d_ADDR -- network address
  41. #* CISCO_SPLIT_INC_%d_MASK -- subnet mask (for example: 255.255.255.0)
  42. #* CISCO_SPLIT_INC_%d_MASKLEN -- subnet masklen (for example: 24)
  43. #* CISCO_SPLIT_INC_%d_PROTOCOL -- protocol (often just 0)
  44. #* CISCO_SPLIT_INC_%d_SPORT -- source port (often just 0)
  45. #* CISCO_SPLIT_INC_%d_DPORT -- destination port (often just 0)
  46. #* CISCO_IPV6_SPLIT_INC -- number of networks in IPv6 split-network-list
  47. #* CISCO_IPV6_SPLIT_INC_%d_ADDR -- IPv6 network address
  48. #* CISCO_IPV6_SPLIT_INC_$%d_MASKLEN -- IPv6 subnet masklen
  49.  
  50. # FIXMEs:
  51.  
  52. # Section A: route handling
  53.  
  54. # 1) The 3 values CISCO_SPLIT_INC_%d_PROTOCOL/SPORT/DPORT are currently being ignored
  55. # In order to use them, we'll probably need os specific solutions
  56. # * Linux: iptables -t mangle -I PREROUTING <conditions> -j ROUTE --oif $TUNDEV
  57. # This would be an *alternative* to changing the routes (and thus 2) and 3)
  58. # shouldn't be relevant at all)
  59. # 2) There are two different functions to set routes: generic routes and the
  60. # default route. Why isn't the defaultroute handled via the generic route case?
  61. # 3) In the split tunnel case, all routes but the default route might get replaced
  62. # without getting restored later. We should explicitely check and save them just
  63. # like the defaultroute
  64. # 4) Replies to a dhcp-server should never be sent into the tunnel
  65.  
  66. # Section B: Split DNS handling
  67.  
  68. # 1) Maybe dnsmasq can do something like that
  69. # 2) Parse dns packets going out via tunnel and redirect them to original dns-server
  70.  
  71. #env | sort
  72. #set -x
  73.  
  74. # =========== script (variable) setup ====================================
  75.  
  76. PATH=/sbin:/usr/sbin:$PATH
  77.  
  78. OS="`uname -s`"
  79.  
  80. HOOKS_DIR=/etc/vpnc
  81. DEFAULT_ROUTE_FILE=/var/run/vpnc/defaultroute
  82. RESOLV_CONF_BACKUP=/var/run/vpnc/resolv.conf-backup
  83. SCRIPTNAME=`basename $0`
  84.  
  85. # some systems, eg. Darwin & FreeBSD, prune /var/run on boot
  86. if [ ! -d "/var/run/vpnc" ]; then
  87. mkdir -p /var/run/vpnc
  88. [ -x /sbin/restorecon ] && /sbin/restorecon /var/run/vpnc
  89. fi
  90.  
  91. # stupid SunOS: no blubber in /usr/local/bin ... (on stdout)
  92. IPROUTE="`which ip 2> /dev/null | grep '^/'`"
  93.  
  94. if ifconfig --help 2>&1 | grep BusyBox > /dev/null; then
  95. ifconfig_syntax_inet=""
  96. else
  97. ifconfig_syntax_inet="inet"
  98. fi
  99.  
  100. if [ "$OS" = "Linux" ]; then
  101. ifconfig_syntax_ptp="pointopoint"
  102. route_syntax_gw="gw"
  103. route_syntax_del="del"
  104. route_syntax_netmask="netmask"
  105. else
  106. ifconfig_syntax_ptp=""
  107. route_syntax_gw=""
  108. route_syntax_del="delete"
  109. route_syntax_netmask="-netmask"
  110. fi
  111. if [ "$OS" = "SunOS" ]; then
  112. route_syntax_interface="-interface"
  113. ifconfig_syntax_ptpv6="$INTERNAL_IP6_ADDRESS"
  114. else
  115. route_syntax_interface=""
  116. ifconfig_syntax_ptpv6=""
  117. fi
  118.  
  119. grep ^hosts /etc/nsswitch.conf|grep resolve >/dev/null 2>&1
  120. if [ $? = 0 ];then
  121. RESOLVEDENABLED=1
  122. else
  123. RESOLVEDENABLED=0
  124. fi
  125.  
  126. if [ -r /etc/openwrt_release ] && [ -n "$OPENWRT_INTERFACE" ]; then
  127. . /etc/functions.sh
  128. include /lib/network
  129. MODIFYRESOLVCONF=modify_resolvconf_openwrt
  130. RESTORERESOLVCONF=restore_resolvconf_openwrt
  131. elif [ -x /usr/bin/busctl ] && [ ${RESOLVEDENABLED} = 1 ]; then # For systemd-resolved (version 229 and above)
  132. MODIFYRESOLVCONF=modify_resolved_manager
  133. RESTORERESOLVCONF=restore_resolved_manager
  134. elif [ -x /sbin/resolvconf ]; then # Optional tool on Debian, Ubuntu, Gentoo and FreeBSD
  135. MODIFYRESOLVCONF=modify_resolvconf_manager
  136. RESTORERESOLVCONF=restore_resolvconf_manager
  137. elif [ -x /sbin/netconfig ]; then # tool on Suse after 11.1
  138. MODIFYRESOLVCONF=modify_resolvconf_suse_netconfig
  139. RESTORERESOLVCONF=restore_resolvconf_suse_netconfig
  140. elif [ -x /sbin/modify_resolvconf ]; then # Mandatory tool on Suse earlier than 11.1
  141. MODIFYRESOLVCONF=modify_resolvconf_suse
  142. RESTORERESOLVCONF=restore_resolvconf_suse
  143. elif [ -x /usr/sbin/unbound-control ] && /usr/sbin/unbound-control status > /dev/null 2>&1; then
  144. MODIFYRESOLVCONF=modify_resolvconf_unbound
  145. RESTORERESOLVCONF=restore_resolvconf_unbound
  146. else # Generic for any OS
  147. MODIFYRESOLVCONF=modify_resolvconf_generic
  148. RESTORERESOLVCONF=restore_resolvconf_generic
  149. fi
  150.  
  151.  
  152. # =========== script hooks =================================================
  153.  
  154. run_hooks() {
  155. HOOK="$1"
  156.  
  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.  
  164. # =========== tunnel interface handling ====================================
  165.  
  166. do_ifconfig() {
  167. if [ -n "$INTERNAL_IP4_MTU" ]; then
  168. MTU=$INTERNAL_IP4_MTU
  169. elif [ -n "$IPROUTE" ]; then
  170. MTUDEV=`$IPROUTE route get "$VPNGATEWAY" | sed -ne 's/^.*dev \([a-z0-9]*\).*$/\1/p'`
  171. MTU=`$IPROUTE link show "$MTUDEV" | sed -ne 's/^.*mtu \([[:digit:]]\+\).*$/\1/p'`
  172. if [ -n "$MTU" ]; then
  173. MTU=`expr $MTU - 88`
  174. fi
  175. fi
  176.  
  177. if [ -z "$MTU" ]; then
  178. MTU=1412
  179. fi
  180.  
  181. # Point to point interface require a netmask of 255.255.255.255 on some systems
  182. if [ -n "$IPROUTE" ]; then
  183. $IPROUTE link set dev "$TUNDEV" up mtu "$MTU"
  184. $IPROUTE addr add "$INTERNAL_IP4_ADDRESS/32" peer "$INTERNAL_IP4_ADDRESS" dev "$TUNDEV"
  185. else
  186. ifconfig "$TUNDEV" ${ifconfig_syntax_inet} "$INTERNAL_IP4_ADDRESS" $ifconfig_syntax_ptp "$INTERNAL_IP4_ADDRESS" netmask 255.255.255.255 mtu ${MTU} up
  187. fi
  188.  
  189. if [ -n "$INTERNAL_IP4_NETMASK" ]; then
  190. set_network_route $INTERNAL_IP4_NETADDR $INTERNAL_IP4_NETMASK $INTERNAL_IP4_NETMASKLEN
  191. fi
  192.  
  193. # If the netmask is provided, it contains the address _and_ netmask
  194. if [ -n "$INTERNAL_IP6_ADDRESS" ] && [ -z "$INTERNAL_IP6_NETMASK" ]; then
  195. INTERNAL_IP6_NETMASK="$INTERNAL_IP6_ADDRESS/128"
  196. fi
  197. if [ -n "$INTERNAL_IP6_NETMASK" ]; then
  198. if [ -n "$IPROUTE" ]; then
  199. $IPROUTE -6 addr add $INTERNAL_IP6_NETMASK dev $TUNDEV
  200. else
  201. # Unlike for Legacy IP, we don't specify the dest_address
  202. # here on *BSD. OpenBSD for one will refuse to accept
  203. # incoming packets to that address if we do.
  204. # OpenVPN does the same (gives dest_address for Legacy IP
  205. # but not for IPv6).
  206. # Only Solaris needs it; hence $ifconfig_syntax_ptpv6
  207. ifconfig "$TUNDEV" inet6 $INTERNAL_IP6_NETMASK $ifconfig_syntax_ptpv6 mtu $MTU up
  208. fi
  209. fi
  210. }
  211.  
  212. destroy_tun_device() {
  213. case "$OS" in
  214. NetBSD|OpenBSD) # and probably others...
  215. ifconfig "$TUNDEV" destroy
  216. ;;
  217. FreeBSD)
  218. ifconfig "$TUNDEV" destroy > /dev/null 2>&1 &
  219. ;;
  220. esac
  221. }
  222.  
  223. # =========== route handling ====================================
  224.  
  225. if [ -n "$IPROUTE" ]; then
  226. fix_ip_get_output () {
  227. sed -e 's/ /\n/g' | \
  228. sed -ne '1p;/via/{N;p};/dev/{N;p};/src/{N;p};/mtu/{N;p}'
  229. }
  230.  
  231. set_vpngateway_route() {
  232. $IPROUTE route add `$IPROUTE route get "$VPNGATEWAY" | fix_ip_get_output`
  233. $IPROUTE route flush cache
  234. }
  235.  
  236. del_vpngateway_route() {
  237. $IPROUTE route $route_syntax_del "$VPNGATEWAY"
  238. $IPROUTE route flush cache
  239. }
  240.  
  241. set_default_route() {
  242. $IPROUTE route | grep '^default' | fix_ip_get_output > "$DEFAULT_ROUTE_FILE"
  243. $IPROUTE route replace default dev "$TUNDEV"
  244. $IPROUTE route flush cache
  245. }
  246.  
  247. set_network_route() {
  248. NETWORK="$1"
  249. NETMASK="$2"
  250. NETMASKLEN="$3"
  251. $IPROUTE route replace "$NETWORK/$NETMASKLEN" dev "$TUNDEV"
  252. $IPROUTE route flush cache
  253. }
  254.  
  255. reset_default_route() {
  256. if [ -s "$DEFAULT_ROUTE_FILE" ]; then
  257. $IPROUTE route replace `cat "$DEFAULT_ROUTE_FILE"`
  258. $IPROUTE route flush cache
  259. rm -f -- "$DEFAULT_ROUTE_FILE"
  260. fi
  261. }
  262.  
  263. del_network_route() {
  264. NETWORK="$1"
  265. NETMASK="$2"
  266. NETMASKLEN="$3"
  267. $IPROUTE route $route_syntax_del "$NETWORK/$NETMASKLEN" dev "$TUNDEV"
  268. $IPROUTE route flush cache
  269. }
  270.  
  271. set_ipv6_default_route() {
  272. # We don't save/restore IPv6 default route; just add a higher-priority one.
  273. $IPROUTE -6 route add default dev "$TUNDEV" metric 1
  274. $IPROUTE -6 route flush cache
  275. }
  276.  
  277. set_ipv6_network_route() {
  278. NETWORK="$1"
  279. NETMASKLEN="$2"
  280. $IPROUTE -6 route replace "$NETWORK/$NETMASKLEN" dev "$TUNDEV"
  281. $IPROUTE route flush cache
  282. }
  283.  
  284. reset_ipv6_default_route() {
  285. $IPROUTE -6 route del default dev "$TUNDEV"
  286. $IPROUTE route flush cache
  287. }
  288.  
  289. del_ipv6_network_route() {
  290. NETWORK="$1"
  291. NETMASKLEN="$2"
  292. $IPROUTE -6 route del "$NETWORK/$NETMASKLEN" dev "$TUNDEV"
  293. $IPROUTE -6 route flush cache
  294. }
  295. else # use route command
  296. get_default_gw() {
  297. # isn't -n supposed to give --numeric output?
  298. # apperently not...
  299. # Get rid of lines containing IPv6 addresses (':')
  300. netstat -r -n | awk '/:/ { next; } /^(default|0\.0\.0\.0)/ { print $2; }'
  301. }
  302.  
  303. set_vpngateway_route() {
  304. route add -host "$VPNGATEWAY" $route_syntax_gw "`get_default_gw`"
  305. }
  306.  
  307. del_vpngateway_route() {
  308. route $route_syntax_del -host "$VPNGATEWAY" $route_syntax_gw "`get_default_gw`"
  309. }
  310.  
  311. set_default_route() {
  312. DEFAULTGW="`get_default_gw`"
  313. echo "$DEFAULTGW" > "$DEFAULT_ROUTE_FILE"
  314. route $route_syntax_del default $route_syntax_gw "$DEFAULTGW"
  315. route add default $route_syntax_gw "$INTERNAL_IP4_ADDRESS" $route_syntax_interface
  316. }
  317.  
  318. set_network_route() {
  319. NETWORK="$1"
  320. NETMASK="$2"
  321. NETMASKLEN="$3"
  322. del_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN"
  323. route add -net "$NETWORK" $route_syntax_netmask "$NETMASK" $route_syntax_gw "$INTERNAL_IP4_ADDRESS" $route_syntax_interface
  324. }
  325.  
  326. reset_default_route() {
  327. if [ -s "$DEFAULT_ROUTE_FILE" ]; then
  328. route $route_syntax_del default $route_syntax_gw "`get_default_gw`" $route_syntax_interface
  329. route add default $route_syntax_gw `cat "$DEFAULT_ROUTE_FILE"`
  330. rm -f -- "$DEFAULT_ROUTE_FILE"
  331. fi
  332. }
  333.  
  334. del_network_route() {
  335. case "$OS" in
  336. Linux|NetBSD|OpenBSD|Darwin|SunOS) # and probably others...
  337. # routes are deleted automatically on device shutdown
  338. return
  339. ;;
  340. esac
  341. NETWORK="$1"
  342. NETMASK="$2"
  343. NETMASKLEN="$3"
  344. route $route_syntax_del -net "$NETWORK" $route_syntax_netmask "$NETMASK" $route_syntax_gw "$INTERNAL_IP4_ADDRESS"
  345. }
  346.  
  347. set_ipv6_default_route() {
  348. route add -inet6 default "$INTERNAL_IP6_ADDRESS" $route_syntax_interface
  349. }
  350.  
  351. set_ipv6_network_route() {
  352. NETWORK="$1"
  353. NETMASK="$2"
  354. route add -inet6 -net "$NETWORK/$NETMASK" "$INTERNAL_IP6_ADDRESS" $route_syntax_interface
  355. :
  356. }
  357.  
  358. reset_ipv6_default_route() {
  359. route $route_syntax_del -inet6 default "$INTERNAL_IP6_ADDRESS"
  360. :
  361. }
  362.  
  363. del_ipv6_network_route() {
  364. NETWORK="$1"
  365. NETMASK="$2"
  366. route $route_syntax_del -inet6 "$NETWORK/$NETMASK" "$INTERNAL_IP6_ADDRESS"
  367. :
  368. }
  369.  
  370. fi
  371.  
  372. # =========== resolv.conf handling ====================================
  373.  
  374. # =========== resolv.conf handling for any OS =========================
  375.  
  376. modify_resolvconf_generic() {
  377. grep '^#@VPNC_GENERATED@' /etc/resolv.conf > /dev/null 2>&1 || cp -- /etc/resolv.conf "$RESOLV_CONF_BACKUP"
  378. NEW_RESOLVCONF="#@VPNC_GENERATED@ -- this file is generated by vpnc
  379. # and will be overwritten by vpnc
  380. # as long as the above mark is intact"
  381.  
  382. DOMAINS="$CISCO_DEF_DOMAIN"
  383.  
  384. exec 6< "$RESOLV_CONF_BACKUP"
  385. while read LINE <&6 ; do
  386. case "$LINE" in
  387. # omit; we will overwrite these
  388. nameserver*) ;;
  389. # extract listed domains and prepend to list
  390. domain* | search*) DOMAINS="${LINE#* } $DOMAINS" ;;
  391. # retain other lines
  392. *) NEW_RESOLVCONF="$NEW_RESOLVCONF
  393. $LINE" ;;
  394. esac
  395. done
  396. exec 6<&-
  397.  
  398. for i in $INTERNAL_IP4_DNS ; do
  399. NEW_RESOLVCONF="$NEW_RESOLVCONF
  400. nameserver $i"
  401. done
  402. # note that "search" is mutually exclusive with "domain";
  403. # "search" allows multiple domains to be listed, so use that
  404. if [ -n "$DOMAINS" ]; then
  405. NEW_RESOLVCONF="$NEW_RESOLVCONF
  406. search $DOMAINS"
  407. fi
  408. echo "$NEW_RESOLVCONF" > /etc/resolv.conf
  409.  
  410. if [ "$OS" = "Darwin" ]; then
  411. case "`uname -r`" in
  412. # Skip for pre-10.4 systems
  413. 4.*|5.*|6.*|7.*)
  414. ;;
  415. # 10.4 and later require use of scutil for DNS to work properly
  416. *)
  417. OVERRIDE_PRIMARY=""
  418. if [ -n "$CISCO_SPLIT_INC" ]; then
  419. if [ $CISCO_SPLIT_INC -lt 1 ]; then
  420. # Must override for correct default route
  421. # Cannot use multiple DNS matching in this case
  422. OVERRIDE_PRIMARY='d.add OverridePrimary # 1'
  423. fi
  424. # Overriding the default gateway breaks split routing
  425. OVERRIDE_GATEWAY=""
  426. # Not overriding the default gateway breaks usage of
  427. # INTERNAL_IP4_DNS. Prepend INTERNAL_IP4_DNS to list
  428. # of used DNS servers
  429. SERVICE=`echo "show State:/Network/Global/IPv4" | scutil | grep -oE '[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}'`
  430. SERVICE_DNS=`echo "show State:/Network/Service/$SERVICE/DNS" | scutil | grep -oE '([0-9]{1,3}[\.]){3}[0-9]{1,3}' | xargs`
  431. if [ X"$SERVICE_DNS" != X"$INTERNAL_IP4_DNS" ]; then
  432. scutil >/dev/null 2>&1 <<-EOF
  433. open
  434. get State:/Network/Service/$SERVICE/DNS
  435. d.add ServerAddresses * $INTERNAL_IP4_DNS $SERVICE_DNS
  436. set State:/Network/Service/$SERVICE/DNS
  437. close
  438. EOF
  439. fi
  440. else
  441. # No split routing. Override default gateway
  442. OVERRIDE_GATEWAY="d.add Router $INTERNAL_IP4_ADDRESS"
  443. fi
  444. # Uncomment the following if/fi pair to use multiple
  445. # DNS matching when available. When multiple DNS matching
  446. # is present, anything reading the /etc/resolv.conf file
  447. # directly will probably not work as intended.
  448. #if [ -z "$CISCO_DEF_DOMAIN" ]; then
  449. # Cannot use multiple DNS matching without a domain
  450. OVERRIDE_PRIMARY='d.add OverridePrimary # 1'
  451. #fi
  452. scutil >/dev/null 2>&1 <<-EOF
  453. open
  454. d.init
  455. d.add ServerAddresses * $INTERNAL_IP4_DNS
  456. set State:/Network/Service/$TUNDEV/DNS
  457. d.init
  458. $OVERRIDE_GATEWAY
  459. d.add Addresses * $INTERNAL_IP4_ADDRESS
  460. d.add SubnetMasks * 255.255.255.255
  461. d.add InterfaceName $TUNDEV
  462. $OVERRIDE_PRIMARY
  463. set State:/Network/Service/$TUNDEV/IPv4
  464. close
  465. EOF
  466. if [ -n "$CISCO_DEF_DOMAIN" ]; then
  467. scutil >/dev/null 2>&1 <<-EOF
  468. open
  469. get State:/Network/Service/$TUNDEV/DNS
  470. d.add DomainName $CISCO_DEF_DOMAIN
  471. d.add SearchDomains * $CISCO_DEF_DOMAIN
  472. d.add SupplementalMatchDomains * $CISCO_DEF_DOMAIN
  473. set State:/Network/Service/$TUNDEV/DNS
  474. close
  475. EOF
  476. fi
  477. ;;
  478. esac
  479. fi
  480. }
  481.  
  482. restore_resolvconf_generic() {
  483. if [ ! -f "$RESOLV_CONF_BACKUP" ]; then
  484. return
  485. fi
  486. grep '^#@VPNC_GENERATED@' /etc/resolv.conf > /dev/null 2>&1 && cat "$RESOLV_CONF_BACKUP" > /etc/resolv.conf
  487. rm -f -- "$RESOLV_CONF_BACKUP"
  488.  
  489. if [ "$OS" = "Darwin" ]; then
  490. case "`uname -r`" in
  491. # Skip for pre-10.4 systems
  492. 4.*|5.*|6.*|7.*)
  493. ;;
  494. # 10.4 and later require use of scutil for DNS to work properly
  495. *)
  496. scutil >/dev/null 2>&1 <<-EOF
  497. open
  498. remove State:/Network/Service/$TUNDEV/IPv4
  499. remove State:/Network/Service/$TUNDEV/DNS
  500. close
  501. EOF
  502. # Split routing required prepending of INTERNAL_IP4_DNS
  503. # to list of used DNS servers
  504. if [ -n "$CISCO_SPLIT_INC" ]; then
  505. SERVICE=`echo "show State:/Network/Global/IPv4" | scutil | grep -oE '[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}'`
  506. SERVICE_DNS=`echo "show State:/Network/Service/$SERVICE/DNS" | scutil | grep -oE '([0-9]{1,3}[\.]){3}[0-9]{1,3}' | xargs`
  507. if [ X"$SERVICE_DNS" != X"$INTERNAL_IP4_DNS" ]; then
  508. scutil >/dev/null 2>&1 <<-EOF
  509. open
  510. get State:/Network/Service/$SERVICE/DNS
  511. d.add ServerAddresses * ${SERVICE_DNS##$INTERNAL_IP4_DNS}
  512. set State:/Network/Service/$SERVICE/DNS
  513. close
  514. EOF
  515. fi
  516. fi
  517. ;;
  518. esac
  519. fi
  520. }
  521. # === resolv.conf handling via /sbin/netconfig (Suse 11.1) =====================
  522.  
  523. # Suse provides a script that modifies resolv.conf. Use it because it will
  524. # restart/reload all other services that care about it (e.g. lwresd). [unclear if this is still true, but probably --mlk]
  525.  
  526. modify_resolvconf_suse_netconfig()
  527. {
  528. /sbin/netconfig modify -s vpnc -i "$TUNDEV" <<-EOF
  529. INTERFACE='$TUNDEV'
  530. DNSSERVERS='$INTERNAL_IP4_DNS'
  531. DNSDOMAIN='$CISCO_DEF_DOMAIN'
  532. EOF
  533. }
  534. # Restore resolv.conf to old contents on Suse
  535. restore_resolvconf_suse_netconfig()
  536. {
  537. /sbin/netconfig remove -s vpnc -i "$TUNDEV"
  538. }
  539.  
  540. # === resolv.conf handling via /sbin/modify_resolvconf (Suse) =====================
  541.  
  542. # Suse provides a script that modifies resolv.conf. Use it because it will
  543. # restart/reload all other services that care about it (e.g. lwresd).
  544.  
  545. modify_resolvconf_suse()
  546. {
  547. FULL_SCRIPTNAME=`readlink -f $0`
  548. RESOLV_OPTS=''
  549. test -n "$INTERNAL_IP4_DNS" && RESOLV_OPTS="-n \"$INTERNAL_IP4_DNS\""
  550. test -n "$CISCO_DEF_DOMAIN" && RESOLV_OPTS="$RESOLV_OPTS -d $CISCO_DEF_DOMAIN"
  551. test -n "$RESOLV_OPTS" && eval /sbin/modify_resolvconf modify -s vpnc -p $SCRIPTNAME -f $FULL_SCRIPTNAME -e $TUNDEV $RESOLV_OPTS -t \"This file was created by $SCRIPTNAME\"
  552. }
  553.  
  554. # Restore resolv.conf to old contents on Suse
  555. restore_resolvconf_suse()
  556. {
  557. FULL_SCRIPTNAME=`readlink -f $0`
  558. /sbin/modify_resolvconf restore -s vpnc -p $SCRIPTNAME -f $FULL_SCRIPTNAME -e $TUNDEV
  559. }
  560.  
  561. # === resolv.conf handling via UCI (OpenWRT) =========
  562.  
  563. modify_resolvconf_openwrt() {
  564. add_dns $OPENWRT_INTERFACE $INTERNAL_IP4_DNS
  565. }
  566.  
  567. restore_resolvconf_openwrt() {
  568. remove_dns $OPENWRT_INTERFACE
  569. }
  570. # === resolv.conf handling via /sbin/resolvconf (Debian, Ubuntu, Gentoo)) =========
  571.  
  572. modify_resolvconf_manager() {
  573. NEW_RESOLVCONF=""
  574. for i in $INTERNAL_IP4_DNS; do
  575. NEW_RESOLVCONF="$NEW_RESOLVCONF
  576. nameserver $i"
  577. done
  578. if [ -n "$CISCO_DEF_DOMAIN" ]; then
  579. NEW_RESOLVCONF="$NEW_RESOLVCONF
  580. domain $CISCO_DEF_DOMAIN"
  581. fi
  582. echo "$NEW_RESOLVCONF" | /sbin/resolvconf -a $TUNDEV
  583. }
  584.  
  585. restore_resolvconf_manager() {
  586. /sbin/resolvconf -d $TUNDEV
  587. }
  588.  
  589. AF_INET=2
  590.  
  591. get_if_index() {
  592. local link
  593. link="$(ip link show dev "$1")" || return $?
  594. echo ${link} | awk -F: '{print $1}'
  595. }
  596.  
  597. busctl_call() {
  598. local dest node
  599. dest=org.freedesktop.resolve1
  600. node=/org/freedesktop/resolve1
  601. busctl call "$dest" "${node}" "${dest}.Manager" "$@"
  602. }
  603.  
  604. busctl_set_nameservers() {
  605. local if_index addresses args addr
  606. if_index=$1
  607. shift
  608. addresses="$@"
  609. args="$if_index $#"
  610. for addr in ${addresses}; do
  611. args="$args ${AF_INET} 4 $(echo $addr | sed 's/[.]/ /g')"
  612. done
  613. busctl_call SetLinkDNS 'ia(iay)' ${args}
  614. }
  615.  
  616. busctl_set_search() {
  617. local if_index domains args domain
  618. if_index=$1
  619. shift
  620. domains="$@"
  621. args="$if_index $#"
  622. for domain in ${domains}; do
  623. args="$args ${domain} false"
  624. done
  625. busctl_call SetLinkDomains 'ia(sb)' ${args}
  626. }
  627.  
  628. modify_resolved_manager() {
  629. local if_index
  630. if_index=$(get_if_index $TUNDEV)
  631. busctl_set_nameservers $if_index $INTERNAL_IP4_DNS
  632. if [ -n "$CISCO_DEF_DOMAIN" ]; then
  633. busctl_set_search $if_index $CISCO_DEF_DOMAIN
  634. fi
  635. }
  636.  
  637. restore_resolved_manager() {
  638. local if_index
  639. if_index=$(get_if_index $TUNDEV)
  640. busctl_call RevertLink 'i' $if_index
  641. }
  642.  
  643. # === resolv.conf handling via unbound =========
  644.  
  645. modify_resolvconf_unbound() {
  646. if [ -n "$CISCO_DEF_DOMAIN" ]; then
  647. /usr/sbin/unbound-control forward_add +i ${CISCO_DEF_DOMAIN} ${INTERNAL_IP4_DNS}
  648. /usr/sbin/unbound-control flush_requestlist
  649. /usr/sbin/unbound-control flush_zone ${CISCO_DEF_DOMAIN}
  650. fi
  651. }
  652.  
  653. restore_resolvconf_unbound() {
  654. if [ -n "$CISCO_DEF_DOMAIN" ]; then
  655. /usr/sbin/unbound-control forward_remove +i ${CISCO_DEF_DOMAIN}
  656. /usr/sbin/unbound-control flush_zone ${CISCO_DEF_DOMAIN}
  657. /usr/sbin/unbound-control flush_requestlist
  658. fi
  659. }
  660.  
  661. # ========= Toplevel state handling =======================================
  662.  
  663. kernel_is_2_6_or_above() {
  664. case `uname -r` in
  665. 1.*|2.[012345]*)
  666. return 1
  667. ;;
  668. *)
  669. return 0
  670. ;;
  671. esac
  672. }
  673.  
  674. do_pre_init() {
  675. if [ "$OS" = "Linux" ]; then
  676. if (exec 6< /dev/net/tun) > /dev/null 2>&1 ; then
  677. :
  678. else # can't open /dev/net/tun
  679. test -e /proc/sys/kernel/modprobe && `cat /proc/sys/kernel/modprobe` tun 2>/dev/null
  680. # fix for broken devfs in kernel 2.6.x
  681. if [ "`readlink /dev/net/tun`" = misc/net/tun \
  682. -a ! -e /dev/net/misc/net/tun -a -e /dev/misc/net/tun ] ; then
  683. ln -sf /dev/misc/net/tun /dev/net/tun
  684. fi
  685. # make sure tun device exists
  686. if [ ! -e /dev/net/tun ]; then
  687. mkdir -p /dev/net
  688. mknod -m 0640 /dev/net/tun c 10 200
  689. [ -x /sbin/restorecon ] && /sbin/restorecon /dev/net/tun
  690. fi
  691. # workaround for a possible latency caused by udev, sleep max. 10s
  692. if kernel_is_2_6_or_above ; then
  693. for x in `seq 100` ; do
  694. (exec 6<> /dev/net/tun) > /dev/null 2>&1 && break;
  695. sleep 0.1
  696. done
  697. fi
  698. fi
  699. elif [ "$OS" = "FreeBSD" ]; then
  700. if ! kldstat -q -m if_tun > /dev/null; then
  701. kldload if_tun
  702. fi
  703.  
  704. if ! ifconfig $TUNDEV > /dev/null; then
  705. ifconfig $TUNDEV create
  706. fi
  707. elif [ "$OS" = "GNU/kFreeBSD" ]; then
  708. if [ ! -e /dev/tun ]; then
  709. kldload if_tun
  710. fi
  711. elif [ "$OS" = "NetBSD" ]; then
  712. :
  713. elif [ "$OS" = "OpenBSD" ]; then
  714. if ! ifconfig $TUNDEV > /dev/null; then
  715. ifconfig $TUNDEV create
  716. fi
  717. :
  718. elif [ "$OS" = "SunOS" ]; then
  719. :
  720. elif [ "$OS" = "Darwin" ]; then
  721. :
  722. fi
  723. }
  724.  
  725. do_connect() {
  726. if [ -n "$CISCO_BANNER" ]; then
  727. echo "Connect Banner:"
  728. echo "$CISCO_BANNER" | while read LINE ; do echo "|" "$LINE" ; done
  729. echo
  730. fi
  731.  
  732. set_vpngateway_route
  733. do_ifconfig
  734. if [ -n "$CISCO_SPLIT_INC" ]; then
  735. i=0
  736. while [ $i -lt $CISCO_SPLIT_INC ] ; do
  737. eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
  738. eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
  739. eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
  740. if [ "$NETWORK" != "0.0.0.0" ]; then
  741. set_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN"
  742. else
  743. set_default_route
  744. fi
  745. i=`expr $i + 1`
  746. done
  747. for i in $INTERNAL_IP4_DNS ; do
  748. echo "$i" | grep : >/dev/null || \
  749. set_network_route "$i" "255.255.255.255" "32"
  750. done
  751. elif [ -n "$INTERNAL_IP4_ADDRESS" ]; then
  752. set_default_route
  753. fi
  754. if [ -n "$CISCO_IPV6_SPLIT_INC" ]; then
  755. i=0
  756. while [ $i -lt $CISCO_IPV6_SPLIT_INC ] ; do
  757. eval NETWORK="\${CISCO_IPV6_SPLIT_INC_${i}_ADDR}"
  758. eval NETMASKLEN="\${CISCO_IPV6_SPLIT_INC_${i}_MASKLEN}"
  759. if [ $NETMASKLEN -lt 128 ]; then
  760. set_ipv6_network_route "$NETWORK" "$NETMASKLEN"
  761. else
  762. set_ipv6_default_route
  763. fi
  764. i=`expr $i + 1`
  765. done
  766. for i in $INTERNAL_IP4_DNS ; do
  767. if echo "$i" | grep : >/dev/null; then
  768. set_ipv6_network_route "$i" "128"
  769. fi
  770. done
  771. elif [ -n "$INTERNAL_IP6_NETMASK" -o -n "$INTERNAL_IP6_ADDRESS" ]; then
  772. set_ipv6_default_route
  773. fi
  774.  
  775. if [ -n "$INTERNAL_IP4_DNS" ]; then
  776. $MODIFYRESOLVCONF
  777. fi
  778. }
  779.  
  780. do_disconnect() {
  781. if [ -n "$CISCO_SPLIT_INC" ]; then
  782. i=0
  783. while [ $i -lt $CISCO_SPLIT_INC ] ; do
  784. eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
  785. eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
  786. eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
  787. if [ "$NETWORK" != "0.0.0.0" ]; then
  788. # FIXME: This doesn't restore previously overwritten
  789. # routes.
  790. del_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN"
  791. else
  792. reset_default_route
  793. fi
  794. i=`expr $i + 1`
  795. done
  796. for i in $INTERNAL_IP4_DNS ; do
  797. del_network_route "$i" "255.255.255.255" "32"
  798. done
  799. else
  800. reset_default_route
  801. fi
  802. if [ -n "$CISCO_IPV6_SPLIT_INC" ]; then
  803. i=0
  804. while [ $i -lt $CISCO_IPV6_SPLIT_INC ] ; do
  805. eval NETWORK="\${CISCO_IPV6_SPLIT_INC_${i}_ADDR}"
  806. eval NETMASKLEN="\${CISCO_IPV6_SPLIT_INC_${i}_MASKLEN}"
  807. if [ $NETMASKLEN -eq 0 ]; then
  808. reset_ipv6_default_route
  809. else
  810. del_ipv6_network_route "$NETWORK" "$NETMASKLEN"
  811. fi
  812. i=`expr $i + 1`
  813. done
  814. for i in $INTERNAL_IP6_DNS ; do
  815. del_ipv6_network_route "$i" "128"
  816. done
  817. elif [ -n "$INTERNAL_IP6_NETMASK" -o -n "$INTERNAL_IP6_ADDRESS" ]; then
  818. reset_ipv6_default_route
  819. fi
  820.  
  821. del_vpngateway_route
  822.  
  823. if [ -n "$INTERNAL_IP4_DNS" ]; then
  824. $RESTORERESOLVCONF
  825. fi
  826.  
  827.  
  828. if [ -n "$IPROUTE" ]; then
  829. if [ -n "$INTERNAL_IP4_ADDRESS" ]; then
  830. $IPROUTE addr del "$INTERNAL_IP4_ADDRESS/255.255.255.255" peer "$INTERNAL_IP4_ADDRESS" dev "$TUNDEV"
  831. fi
  832. # If the netmask is provided, it contains the address _and_ netmask
  833. if [ -n "$INTERNAL_IP6_ADDRESS" ] && [ -z "$INTERNAL_IP6_NETMASK" ]; then
  834. INTERNAL_IP6_NETMASK="$INTERNAL_IP6_ADDRESS/128"
  835. fi
  836. if [ -n "$INTERNAL_IP6_NETMASK" ]; then
  837. $IPROUTE -6 addr del $INTERNAL_IP6_NETMASK dev $TUNDEV
  838. fi
  839. else
  840. if [ -n "$INTERNAL_IP4_ADDRESS" ]; then
  841. ifconfig "$TUNDEV" 0.0.0.0
  842. fi
  843. if [ -n "$INTERNAL_IP6_ADDRESS" ] && [ -z "$INTERNAL_IP6_NETMASK" ]; then
  844. INTERNAL_IP6_NETMASK="$INTERNAL_IP6_ADDRESS/128"
  845. fi
  846. if [ -n "$INTERNAL_IP6_NETMASK" ]; then
  847. ifconfig "$TUNDEV" inet6 del $INTERNAL_IP6_NETMASK
  848. fi
  849. fi
  850.  
  851. destroy_tun_device
  852. }
  853.  
  854. #### Main
  855.  
  856. if [ -z "$reason" ]; then
  857. echo "this script must be called from vpnc" 1>&2
  858. exit 1
  859. fi
  860.  
  861. case "$reason" in
  862. pre-init)
  863. run_hooks pre-init
  864. do_pre_init
  865. ;;
  866. connect)
  867. run_hooks connect
  868. do_connect
  869. run_hooks post-connect
  870. ;;
  871. disconnect)
  872. run_hooks disconnect
  873. do_disconnect
  874. run_hooks post-disconnect
  875. ;;
  876. reconnect)
  877. run_hooks reconnect
  878. ;;
  879. *)
  880. echo "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
  881. exit 1
  882. ;;
  883. esac
  884.  
  885. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement