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.

241 lines
5.2 KiB

  1. #!/bin/sh /etc/rc.common
  2. # Copyright (C) 2011 OpenWrt.org
  3. # Copyright (C) 2011 Linus Lüssing
  4. # Based on Jo-Philipp Wich's OpenVPN init script
  5. # This is free software, licensed under the GNU General Public License v2.
  6. # See /LICENSE for more information.
  7. START=42
  8. SERVICE_USE_PID=1
  9. BIN=/usr/sbin/tincd
  10. EXTRA_COMMANDS="up down"
  11. LIST_SEP="
  12. "
  13. TMP_TINC="/tmp/tinc"
  14. append_param() {
  15. local v="$1"
  16. case "$v" in
  17. *_*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
  18. *_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
  19. *_*) v=${v%%_*}-${v#*_} ;;
  20. esac
  21. ARGS="$ARGS --$v"
  22. return 0
  23. }
  24. append_conf_bools() {
  25. local p; local v; local s="$1"; local f="$2"; shift; shift
  26. for p in $*; do
  27. config_get_bool v "$s" "$p"
  28. [ "$v" == 1 ] && echo "$p = yes" >> "$f"
  29. [ "$v" == 0 ] && echo "$p = no" >> "$f"
  30. done
  31. }
  32. append_params() {
  33. local p; local v; local s="$1"; shift
  34. for p in $*; do
  35. config_get v "$s" "$p"
  36. IFS="$LIST_SEP"
  37. for v in $v; do
  38. [ -n "$v" ] && append_param "$p" && ARGS="$ARGS=$v"
  39. done
  40. unset IFS
  41. done
  42. }
  43. append_conf_params() {
  44. local p; local v; local s="$1"; local f="$2"; shift; shift
  45. for p in $*; do
  46. config_get v "$s" "$p"
  47. IFS="$LIST_SEP"
  48. for v in $v; do
  49. # Look up OpenWRT interface names
  50. [ "$p" = "BindToInterface" ] && {
  51. local ifname=$(uci -P /var/state get network.$v.ifname 2>&-)
  52. [ -n "$ifname" ] && v="$ifname"
  53. }
  54. [ -n "$v" ] && echo "$p = $v" >> "$f"
  55. done
  56. unset IFS
  57. done
  58. }
  59. section_enabled() {
  60. config_get_bool enabled "$1" 'enabled' 0
  61. [ $enabled -gt 0 ]
  62. }
  63. prepare_host() {
  64. local s="$1"
  65. local n
  66. # net disabled?
  67. config_get n "$s" net
  68. section_enabled "$n" || return 1
  69. if [ "$#" = "2" ]; then
  70. [ "$2" != "$n" ] && return 1
  71. fi
  72. # host disabled?
  73. section_enabled "$s" || {
  74. [ -f "$TMP_TINC/$n/hosts/$s" ] && rm "$TMP_TINC/$n/hosts/$s"
  75. return 1
  76. }
  77. [ ! -f "/etc/tinc/$n/hosts/$s" ] && {
  78. echo -n "tinc: Warning, public key for $s for network $n "
  79. echo -n "missing in /etc/tinc/$n/hosts/$s, "
  80. echo "skipping configuration of $s"
  81. return 1
  82. }
  83. # append flags
  84. append_conf_bools "$s" "$TMP_TINC/$n/hosts/$s" \
  85. ClampMSS IndirectData PMTUDiscovery TCPOnly
  86. # append params
  87. append_conf_params "$s" "$TMP_TINC/$n/hosts/$s" \
  88. Address Cipher Compression Digest MACLength PMTU \
  89. Port PublicKey PublicKeyFile Subnet
  90. }
  91. check_gen_own_key() {
  92. local s="$1"; local n; local k
  93. config_get n "$s" Name
  94. config_get_bool k "$s" generate_keys 0
  95. [ "$k" == 0 ] && return 0
  96. ([ -z "$n" ] || [ -f "$TMP_TINC/$s/hosts/$n" ] || [ -f "$TMP_TINC/$s/rsa_key.priv" ]) && \
  97. return 0
  98. [ ! -d "$TMP_TINC/$s/hosts" ] && mkdir -p "$TMP_TINC/$s/hosts"
  99. config_get k "$s" key_size
  100. if [ -z "$k" ]; then
  101. $BIN -c "$TMP_TINC/$s" --generate-keys </dev/null
  102. else
  103. $BIN -c "$TMP_TINC/$s" "--generate-keys=$k" </dev/null
  104. fi
  105. [ ! -d "/etc/tinc/$s/hosts" ] && mkdir -p "/etc/tinc/$s/hosts"
  106. cp "$TMP_TINC/$s/rsa_key.priv" "/etc/tinc/$s/"
  107. [ -n "$n" ] && cp "$TMP_TINC/$s/hosts/$n" "/etc/tinc/$s/hosts/"
  108. }
  109. prepare_net() {
  110. local s="$1"
  111. local n
  112. section_enabled "$s" || return 1
  113. # rm old config
  114. rm -rf "$TMP_TINC/$s/"
  115. [ ! -d "$TMP_TINC/$s" ] && mkdir -p "$TMP_TINC/$s"
  116. [ -d "/etc/tinc/$s" ] && cp -r "/etc/tinc/$s" "$TMP_TINC/"
  117. # append flags
  118. append_conf_bools "$s" "$TMP_TINC/$s/tinc.conf" \
  119. DecrementTTL DirectOnly Hostnames IffOneQueue \
  120. LocalDiscovery PriorityInheritance StrictSubnets TunnelServer \
  121. ClampMSS IndirectData PMTUDiscovery TCPOnly
  122. # append params
  123. append_conf_params "$s" "$TMP_TINC/$s/tinc.conf" \
  124. AddressFamily BindToAddress ConnectTo BindToInterface \
  125. Broadcast Device DeviceType Forwarding \
  126. GraphDumpFile Interface KeyExpire MACExpire \
  127. MaxTimeout Mode Name PingInterval PingTimeout \
  128. PrivateKey PrivateKeyFile ProcessPriority ReplayWindow \
  129. UDPRcvBuf UDPSndBuf \
  130. Address Cipher Compression Digest MACLength PMTU \
  131. Port PublicKey PublicKeyFile Subnet
  132. check_gen_own_key "$s" && return 0
  133. }
  134. start_instance() {
  135. local s="$1"
  136. section_enabled "$s" || return 1
  137. ARGS=""
  138. # append params
  139. append_params "$s" logfile debug
  140. SERVICE_PID_FILE="/var/run/tinc.$s.pid"
  141. service_start $BIN -c "$TMP_TINC/$s" -n $s $ARGS --pidfile="$SERVICE_PID_FILE"
  142. }
  143. stop_instance() {
  144. local s="$1"
  145. section_enabled "$s" || return 1
  146. SERVICE_PID_FILE="/var/run/tinc.$s.pid"
  147. service_stop $BIN
  148. # rm old config
  149. rm -rf "$TMP_TINC/$s/"
  150. }
  151. reload_instance() {
  152. local s="$1"
  153. section_enabled "$s" || return 1
  154. SERVICE_PID_FILE="/var/run/tinc.$s.pid"
  155. service_reload $BIN
  156. }
  157. start() {
  158. config_load 'tinc'
  159. config_foreach prepare_net 'tinc-net'
  160. config_foreach prepare_host 'tinc-host'
  161. config_foreach start_instance 'tinc-net'
  162. }
  163. stop() {
  164. config_load 'tinc'
  165. config_foreach stop_instance 'tinc-net'
  166. }
  167. reload() {
  168. config_load 'tinc'
  169. config_foreach reload_instance 'tinc-net'
  170. }
  171. up() {
  172. local exists
  173. local instance
  174. config_load 'tinc'
  175. for instance in "$@"; do
  176. config_get exists "$instance" 'TYPE'
  177. if [ "$exists" == "tinc-net" ]; then
  178. prepare_net "$instance"
  179. config_foreach prepare_host 'tinc-host' "$instance"
  180. start_instance "$instance"
  181. fi
  182. done
  183. }
  184. down() {
  185. local exists
  186. local instance
  187. config_load 'tinc'
  188. for instance in "$@"; do
  189. config_get exists "$instance" 'TYPE'
  190. if [ "$exists" == "tinc-net" ]; then
  191. stop_instance "$instance"
  192. fi
  193. done
  194. }