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.
 
 
 
 
 
 

239 lines
5.1 KiB

#!/bin/sh /etc/rc.common
# Copyright (C) 2011 OpenWrt.org
# Copyright (C) 2011 Linus Lüssing
# Based on Jo-Philipp Wich's OpenVPN init script
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
START=42
SERVICE_USE_PID=1
BIN=/usr/sbin/tincd
EXTRA_COMMANDS="up down"
LIST_SEP="
"
TMP_TINC="/tmp/tinc"
append_param() {
local v="$1"
case "$v" in
*_*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
*_*) v=${v%%_*}-${v#*_} ;;
esac
ARGS="$ARGS --$v"
return 0
}
append_conf_bools() {
local p; local v; local s="$1"; local f="$2"; shift; shift
for p in $*; do
config_get_bool v "$s" "$p"
[ "$v" == 1 ] && echo "$p = yes" >> "$f"
[ "$v" == 0 ] && echo "$p = no" >> "$f"
done
}
append_params() {
local p; local v; local s="$1"; shift
for p in $*; do
config_get v "$s" "$p"
IFS="$LIST_SEP"
for v in $v; do
[ -n "$v" ] && append_param "$p" && ARGS="$ARGS=$v"
done
unset IFS
done
}
append_conf_params() {
local p; local v; local s="$1"; local f="$2"; shift; shift
for p in $*; do
config_get v "$s" "$p"
IFS="$LIST_SEP"
for v in $v; do
# Look up OpenWRT interface names
[ "$p" = "BindToInterface" ] && {
local ifname=$(uci -P /var/state get network.$v.ifname 2>&-)
[ -n "$ifname" ] && v="$ifname"
}
[ -n "$v" ] && echo "$p = $v" >> "$f"
done
unset IFS
done
}
section_enabled() {
config_get_bool enabled "$1" 'enabled' 0
[ $enabled -gt 0 ]
}
prepare_host() {
local s="$1"
local n
# net disabled?
config_get n "$s" net
section_enabled "$n" || return 1
if [ "$#" = "2" ]; then
[ "$2" != "$n" ] && return 1
fi
# host disabled?
section_enabled "$s" || {
[ -f "$TMP_TINC/$n/hosts/$s" ] && rm "$TMP_TINC/$n/hosts/$s"
return 1
}
[ ! -f "/etc/tinc/$n/hosts/$s" ] && {
echo -n "tinc: Warning, public key for $s for network $n "
echo -n "missing in /etc/tinc/$n/hosts/$s, "
echo "skipping configuration of $s"
return 1
}
# append flags
append_conf_bools "$s" "$TMP_TINC/$n/hosts/$s" \
ClampMSS IndirectData PMTUDiscovery TCPOnly
# append params
append_conf_params "$s" "$TMP_TINC/$n/hosts/$s" \
Address Cipher Compression Digest MACLength PMTU \
Port PublicKey PublicKeyFile Subnet
}
check_gen_own_key() {
local s="$1"; local n; local k
config_get n "$s" Name
config_get_bool k "$s" generate_keys 0
[ "$k" == 0 ] && return 0
([ -z "$n" ] || [ -f "$TMP_TINC/$s/hosts/$n" ] || [ -f "$TMP_TINC/$s/rsa_key.priv" ]) && \
return 0
[ ! -d "$TMP_TINC/$s/hosts" ] && mkdir -p "$TMP_TINC/$s/hosts"
config_get k "$s" key_size
if [ -z "$k" ]; then
$BIN -c "$TMP_TINC/$s" --generate-keys </dev/null
else
$BIN -c "$TMP_TINC/$s" "--generate-keys=$k" </dev/null
fi
[ ! -d "/etc/tinc/$s/hosts" ] && mkdir -p "/etc/tinc/$s/hosts"
cp "$TMP_TINC/$s/rsa_key.priv" "/etc/tinc/$s/"
[ -n "$n" ] && cp "$TMP_TINC/$s/hosts/$n" "/etc/tinc/$s/hosts/"
}
prepare_net() {
local s="$1"
local n
section_enabled "$s" || return 1
[ -d "$TMP_TINC/$s" ] && rm -rf "$TMP_TINC/$s/"
mkdir -p "$TMP_TINC/$s"
[ -d "/etc/tinc/$s" ] && cp -r "/etc/tinc/$s" "$TMP_TINC/"
# append flags
append_conf_bools "$s" "$TMP_TINC/$s/tinc.conf" \
DecrementTTL DirectOnly Hostnames IffOneQueue \
LocalDiscovery PriorityInheritance StrictSubnets TunnelServer \
ClampMSS IndirectData PMTUDiscovery TCPOnly
# append params
append_conf_params "$s" "$TMP_TINC/$s/tinc.conf" \
AddressFamily BindToAddress ConnectTo BindToInterface \
Broadcast Device DeviceType Forwarding \
GraphDumpFile Interface KeyExpire MACExpire \
MaxTimeout Mode Name PingInterval PingTimeout \
PrivateKey PrivateKeyFile ProcessPriority ReplayWindow \
UDPRcvBuf UDPSndBuf \
Address Cipher Compression Digest MACLength PMTU \
Port PublicKey PublicKeyFile Subnet
check_gen_own_key "$s" && return 0
}
start_instance() {
local s="$1"
section_enabled "$s" || return 1
ARGS=""
# append params
append_params "$s" logfile debug
SERVICE_PID_FILE="/var/run/tinc.$s.pid"
service_start $BIN -c "$TMP_TINC/$s" -n $s $ARGS --pidfile="$SERVICE_PID_FILE"
}
stop_instance() {
local s="$1"
section_enabled "$s" || return 1
SERVICE_PID_FILE="/var/run/tinc.$s.pid"
service_stop $BIN
# rm old config
rm -rf "$TMP_TINC/$s/"
}
reload_instance() {
local s="$1"
section_enabled "$s" || return 1
SERVICE_PID_FILE="/var/run/tinc.$s.pid"
service_reload $BIN
}
start() {
config_load 'tinc'
config_foreach prepare_net 'tinc-net'
config_foreach prepare_host 'tinc-host'
config_foreach start_instance 'tinc-net'
}
stop() {
config_load 'tinc'
config_foreach stop_instance 'tinc-net'
}
reload() {
config_load 'tinc'
config_foreach reload_instance 'tinc-net'
}
up() {
local exists
local instance
config_load 'tinc'
for instance in "$@"; do
config_get exists "$instance" 'TYPE'
if [ "$exists" == "tinc-net" ]; then
prepare_net "$instance"
config_foreach prepare_host 'tinc-host' "$instance"
start_instance "$instance"
fi
done
}
down() {
local exists
local instance
config_load 'tinc'
for instance in "$@"; do
config_get exists "$instance" 'TYPE'
if [ "$exists" == "tinc-net" ]; then
stop_instance "$instance"
fi
done
}