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.

301 lines
6.0 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. if ( type extra_command >/dev/null 2>&1 ); then
  11. extra_command "up" "<instance> Setting instance up"
  12. extra_command "down" "<instance> Setting instance down"
  13. else
  14. EXTRA_COMMANDS="up down"
  15. fi
  16. LIST_SEP="
  17. "
  18. TMP_TINC="/tmp/tinc"
  19. append_param() {
  20. local v="$1"
  21. case "$v" in
  22. *_*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
  23. *_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
  24. *_*) v=${v%%_*}-${v#*_} ;;
  25. esac
  26. ARGS="$ARGS --$v"
  27. return 0
  28. }
  29. append_conf_bools() {
  30. local p; local v; local s="$1"; local f="$2"; shift; shift
  31. for p in $*; do
  32. config_get_bool v "$s" "$p"
  33. [ "$v" == 1 ] && echo "$p = yes" >> "$f"
  34. [ "$v" == 0 ] && echo "$p = no" >> "$f"
  35. done
  36. }
  37. append_params() {
  38. local p; local v; local s="$1"; shift
  39. for p in $*; do
  40. config_get v "$s" "$p"
  41. IFS="$LIST_SEP"
  42. for v in $v; do
  43. [ -n "$v" ] && append_param "$p" && ARGS="$ARGS=$v"
  44. done
  45. unset IFS
  46. done
  47. }
  48. append_conf_params() {
  49. local p; local v; local s="$1"; local f="$2"; shift; shift
  50. for p in $*; do
  51. config_get v "$s" "$p"
  52. IFS="$LIST_SEP"
  53. for v in $v; do
  54. # Look up OpenWRT interface names
  55. [ "$p" = "BindToInterface" ] && {
  56. local ifname=$(uci -P /var/state get network.$v.ifname 2>&-)
  57. [ -n "$ifname" ] && v="$ifname"
  58. }
  59. [ -n "$v" ] && echo "$p = $v" >> "$f"
  60. done
  61. unset IFS
  62. done
  63. }
  64. section_enabled() {
  65. config_get_bool enabled "$1" 'enabled' 0
  66. [ $enabled -gt 0 ]
  67. }
  68. prepare_host() {
  69. local s="$1"
  70. local n
  71. # net disabled?
  72. config_get n "$s" net
  73. section_enabled "$n" || return 1
  74. if [ "$#" = "2" ]; then
  75. [ "$2" != "$n" ] && return 1
  76. fi
  77. HOST_CONF_FILE="$TMP_TINC/$n/hosts/$s"
  78. MANDATORY_PARAM_IN_UCI=0
  79. [ ! -f "/etc/tinc/$n/hosts/$s" ] && {
  80. config_get pk "$s" "PublicKey"
  81. config_get na "$s" "Name"
  82. if [ -n "$pk" -a -n "$na" ] ; then
  83. HOST_CONF_FILE="$TMP_TINC/$n/hosts/$na"
  84. MANDATORY_PARAM_IN_UCI=1
  85. fi
  86. }
  87. # host disabled?
  88. section_enabled "$s" || {
  89. [ -f "$HOST_CONF_FILE" ] && rm "$HOST_CONF_FILE"
  90. return 1
  91. }
  92. [ ! -f "/etc/tinc/$n/hosts/$s" ] && {
  93. if [ "$MANDATORY_PARAM_IN_UCI" -eq 1 ] ; then
  94. touch "$HOST_CONF_FILE" ;
  95. else
  96. echo -n "tinc: Warning, public key for $s for network $n "
  97. echo -n "missing in /etc/tinc/$n/hosts/$s, "
  98. echo "skipping configuration of $s"
  99. return 1
  100. fi
  101. }
  102. # append flags
  103. append_conf_bools "$s" "$HOST_CONF_FILE" \
  104. ClampMSS IndirectData PMTUDiscovery TCPOnly
  105. # append params
  106. append_conf_params "$s" "$HOST_CONF_FILE" \
  107. Address Cipher Compression Digest Ed25519PublicKey MACLength Name PMTU \
  108. Port PublicKey PublicKeyFile Subnet
  109. }
  110. check_gen_own_key() {
  111. local s="$1"; local n; local k
  112. config_get n "$s" Name
  113. config_get_bool k "$s" generate_keys 0
  114. [ "$k" == 0 ] && return 0
  115. ([ -z "$n" ] || [ -f "$TMP_TINC/$s/hosts/$n" ] || [ -f "$TMP_TINC/$s/rsa_key.priv" ]) && \
  116. return 0
  117. [ ! -d "$TMP_TINC/$s/hosts" ] && mkdir -p "$TMP_TINC/$s/hosts"
  118. config_get k "$s" key_size
  119. if [ -z "$k" ]; then
  120. $BIN -c "$TMP_TINC/$s" --generate-keys </dev/null
  121. else
  122. $BIN -c "$TMP_TINC/$s" "--generate-keys=$k" </dev/null
  123. fi
  124. [ ! -d "/etc/tinc/$s/hosts" ] && mkdir -p "/etc/tinc/$s/hosts"
  125. cp "$TMP_TINC/$s/rsa_key.priv" "/etc/tinc/$s/"
  126. [ -n "$n" ] && cp "$TMP_TINC/$s/hosts/$n" "/etc/tinc/$s/hosts/"
  127. }
  128. prepare_net() {
  129. local s="$1"
  130. local n
  131. section_enabled "$s" || return 1
  132. [ -d "$TMP_TINC/$s" ] && rm -rf "$TMP_TINC/$s/"
  133. mkdir -p "$TMP_TINC/$s"
  134. [ -d "/etc/tinc/$s" ] && cp -r "/etc/tinc/$s" "$TMP_TINC/"
  135. # append flags
  136. append_conf_bools "$s" "$TMP_TINC/$s/tinc.conf" \
  137. AutoConnect \
  138. DecrementTTL \
  139. DeviceStandby \
  140. DirectOnly \
  141. ExperimentalProtocol \
  142. Hostnames \
  143. LocalDiscovery \
  144. PriorityInheritance \
  145. StrictSubnets \
  146. TunnelServer \
  147. ClampMSS \
  148. IndirectData \
  149. PMTUDiscovery \
  150. TCPOnly
  151. # append params
  152. append_conf_params "$s" "$TMP_TINC/$s/tinc.conf" \
  153. AddressFamily \
  154. BindToAddress \
  155. BindToInterface \
  156. Broadcast \
  157. BroadcastSubnet \
  158. ConnectTo \
  159. Device \
  160. DeviceType \
  161. Ed25519PrivateKeyFile \
  162. ECDSAPublicKey \
  163. Forwarding \
  164. Interface \
  165. ListenAddress \
  166. LocalDiscoveryAddress \
  167. Mode \
  168. KeyExpire \
  169. MACExpire \
  170. MaxConnectionBurst \
  171. Name \
  172. PingInterval \
  173. PingTimeout \
  174. PrivateKey \
  175. PrivateKeyFile \
  176. ProcessPriority \
  177. Proxy \
  178. ReplayWindow \
  179. UDPRcvBuf \
  180. UDPSndBuf \
  181. Address \
  182. Cipher \
  183. Compression \
  184. Digest \
  185. MACLength \
  186. PMTU \
  187. Port \
  188. PublicKey \
  189. PublicKeyFile \
  190. Subnet \
  191. Weight
  192. check_gen_own_key "$s" && return 0
  193. }
  194. start_instance() {
  195. local s="$1"
  196. section_enabled "$s" || return 1
  197. ARGS=""
  198. # append params
  199. append_params "$s" logfile debug
  200. SERVICE_PID_FILE="/var/run/tinc.$s.pid"
  201. service_start $BIN -c "$TMP_TINC/$s" $ARGS --pidfile="$SERVICE_PID_FILE"
  202. }
  203. stop_instance() {
  204. local s="$1"
  205. section_enabled "$s" || return 1
  206. SERVICE_PID_FILE="/var/run/tinc.$s.pid"
  207. service_stop $BIN
  208. # rm old config
  209. rm -rf "$TMP_TINC/$s/"
  210. }
  211. reload_instance() {
  212. local s="$1"
  213. section_enabled "$s" || return 1
  214. SERVICE_PID_FILE="/var/run/tinc.$s.pid"
  215. service_reload $BIN
  216. }
  217. start() {
  218. config_load 'tinc'
  219. config_foreach prepare_net 'tinc-net'
  220. config_foreach prepare_host 'tinc-host'
  221. config_foreach start_instance 'tinc-net'
  222. }
  223. stop() {
  224. config_load 'tinc'
  225. config_foreach stop_instance 'tinc-net'
  226. }
  227. reload() {
  228. config_load 'tinc'
  229. config_foreach reload_instance 'tinc-net'
  230. }
  231. up() {
  232. local exists
  233. local instance
  234. config_load 'tinc'
  235. for instance in "$@"; do
  236. config_get exists "$instance" 'TYPE'
  237. if [ "$exists" == "tinc-net" ]; then
  238. prepare_net "$instance"
  239. config_foreach prepare_host 'tinc-host' "$instance"
  240. start_instance "$instance"
  241. fi
  242. done
  243. }
  244. down() {
  245. local exists
  246. local instance
  247. config_load 'tinc'
  248. for instance in "$@"; do
  249. config_get exists "$instance" 'TYPE'
  250. if [ "$exists" == "tinc-net" ]; then
  251. stop_instance "$instance"
  252. fi
  253. done
  254. }