openvpn: fix invoking user up & down commands from hotplug wrapper
[feed/packages.git] / net / openvpn / files / openvpn.init
1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2008-2013 OpenWrt.org
3 # Copyright (C) 2008 Jo-Philipp Wich
4 # This is free software, licensed under the GNU General Public License v2.
5 # See /LICENSE for more information.
6
7 START=90
8 STOP=10
9
10 USE_PROCD=1
11 PROG=/usr/sbin/openvpn
12
13 LIST_SEP="
14 "
15
16 UCI_STARTED=
17 UCI_DISABLED=
18
19 append_param() {
20 local s="$1"
21 local v="$2"
22 case "$v" in
23 *_*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
24 *_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
25 *_*) v=${v%%_*}-${v#*_} ;;
26 esac
27 echo -n "$v" >> "/var/etc/openvpn-$s.conf"
28 return 0
29 }
30
31 append_bools() {
32 local p; local v; local s="$1"; shift
33 for p in $*; do
34 config_get_bool v "$s" "$p"
35 [ "$v" = 1 ] && append_param "$s" "$p" && echo >> "/var/etc/openvpn-$s.conf"
36 done
37 }
38
39 append_params() {
40 local p; local v; local s="$1"; shift
41 for p in $*; do
42 config_get v "$s" "$p"
43 IFS="$LIST_SEP"
44 for v in $v; do
45 [ -n "$v" ] && [ "$p" != "push" ] && append_param "$s" "$p" && echo " $v" >> "/var/etc/openvpn-$s.conf"
46 [ -n "$v" ] && [ "$p" = "push" ] && append_param "$s" "$p" && echo " \"$v\"" >> "/var/etc/openvpn-$s.conf"
47 done
48 unset IFS
49 done
50 }
51
52 append_list() {
53 local p; local v; local s="$1"; shift
54
55 list_cb_append() {
56 v="${v}:$1"
57 }
58
59 for p in $*; do
60 unset v
61 config_list_foreach "$s" "$p" list_cb_append
62 [ -n "$v" ] && append_param "$s" "$p" && echo " ${v:1}" >> "/var/etc/openvpn-$s.conf"
63 done
64 }
65
66 section_enabled() {
67 config_get_bool enable "$1" 'enable' 0
68 config_get_bool enabled "$1" 'enabled' 0
69 [ $enable -gt 0 ] || [ $enabled -gt 0 ]
70 }
71
72 create_temp_file() {
73 mkdir -p "$(dirname "$1")"
74 rm -f "$1"
75 touch "$1"
76 chown root "$1"
77 chmod 0600 "$1"
78 }
79
80 openvpn_get_dev() {
81 local dev dev_type
82 local name="$1"
83 local conf="$2"
84
85 # Do override only for configurations with config_file
86 config_get config_file "$name" config
87 [ -n "$config_file" ] || return
88
89 # Check there is someething to override
90 config_get dev "$name" dev
91 config_get dev_type "$name" dev_type
92 [ -n "$dev" ] || return
93
94 # If there is a no dev_type, try to guess it
95 if [ -z "$dev_type" ]; then
96 . /lib/functions/openvpn.sh
97
98 local odev odev_type
99 get_openvpn_option "$conf" odev dev
100 get_openvpn_option "$conf" odev_type dev-type
101 [ -n "$odev_type" ] || odev_type="$odev"
102
103 case "$odev_type" in
104 tun*) dev_type="tun" ;;
105 tap*) dev_type="tap" ;;
106 *) return;;
107 esac
108 fi
109
110 # Return overrides
111 echo "--dev-type $dev_type --dev $dev"
112 }
113
114 openvpn_get_credentials() {
115 local name="$1"
116 local ret=""
117
118 config_get cert_password "$name" cert_password
119 config_get password "$name" password
120 config_get username "$name" username
121
122 if [ -n "$cert_password" ]; then
123 create_temp_file /var/run/openvpn.$name.pass
124 echo "$cert_password" > /var/run/openvpn.$name.pass
125 ret=" --askpass /var/run/openvpn.$name.pass "
126 fi
127
128 if [ -n "$username" ]; then
129 create_temp_file /var/run/openvpn.$name.userpass
130 echo "$username" > /var/run/openvpn.$name.userpass
131 echo "$password" >> /var/run/openvpn.$name.userpass
132 ret=" --auth-user-pass /var/run/openvpn.$name.userpass "
133 fi
134
135 # Return overrides
136 echo "$ret"
137 }
138
139 openvpn_add_instance() {
140 local name="$1"
141 local dir="$2"
142 local conf="$3"
143 local security="$4"
144 local up="$5"
145 local down="$6"
146
147 procd_open_instance "$name"
148 procd_set_param command "$PROG" \
149 --syslog "openvpn($name)" \
150 --status "/var/run/openvpn.$name.status" \
151 --cd "$dir" \
152 --config "$conf" \
153 --up "/usr/libexec/openvpn-hotplug up $name" \
154 --down "/usr/libexec/openvpn-hotplug down $name" \
155 ${up:+--setenv user_up "$up"} \
156 ${down:+--setenv user_down "$down"} \
157 --script-security "${security:-2}" \
158 $(openvpn_get_dev "$name" "$conf") \
159 $(openvpn_get_credentials "$name" "$conf")
160 procd_set_param file "$dir/$conf"
161 procd_set_param term_timeout 15
162 procd_set_param respawn
163 procd_append_param respawn 3600
164 procd_append_param respawn 5
165 procd_append_param respawn -1
166 procd_close_instance
167 }
168
169 start_instance() {
170 local s="$1"
171
172 config_get config "$s" config
173 config="${config:+$(readlink -f "$config")}"
174
175 section_enabled "$s" || {
176 append UCI_DISABLED "$config" "$LIST_SEP"
177 return 1
178 }
179
180 local up down script_security
181 config_get up "$s" up
182 config_get down "$s" down
183 config_get script_security "$s" script_security
184
185 [ ! -d "/var/run" ] && mkdir -p "/var/run"
186
187 if [ ! -z "$config" ]; then
188 append UCI_STARTED "$config" "$LIST_SEP"
189 [ -n "$up" ] || get_openvpn_option "$config" up up
190 [ -n "$down" ] || get_openvpn_option "$config" down down
191 openvpn_add_instance "$s" "${config%/*}" "$config" "$script_security" "$up" "$down"
192 return
193 fi
194
195 create_temp_file "/var/etc/openvpn-$s.conf"
196
197 append_bools "$s" $OPENVPN_BOOLS
198 append_params "$s" $OPENVPN_PARAMS
199 append_list "$s" $OPENVPN_LIST
200
201 openvpn_add_instance "$s" "/var/etc" "openvpn-$s.conf" "$script_security" "$up" "$down"
202 }
203
204 start_service() {
205 local instance="$1"
206 local instance_found=0
207
208 config_cb() {
209 local type="$1"
210 local name="$2"
211 if [ "$type" = "openvpn" ]; then
212 if [ -n "$instance" -a "$instance" = "$name" ]; then
213 instance_found=1
214 fi
215 fi
216 }
217
218 . /lib/functions/openvpn.sh
219 . /usr/share/openvpn/openvpn.options
220 config_load 'openvpn'
221
222 if [ -n "$instance" ]; then
223 [ "$instance_found" -gt 0 ] || return
224 start_instance "$instance"
225 else
226 config_foreach start_instance 'openvpn'
227
228 local path name up down
229 for path in /etc/openvpn/*.conf; do
230 if [ -f "$path" ]; then
231 name="${path##*/}"; name="${name%.conf}"
232
233 # don't start configs again that are already started by uci
234 if echo "$UCI_STARTED" | grep -qxF "$path"; then
235 continue
236
237 # don't start configs which are set to disabled in uci
238 elif echo "$UCI_DISABLED" | grep -qxF "$path"; then
239 logger -t openvpn "$name.conf is disabled in /etc/config/openvpn"
240 continue
241 fi
242
243 get_openvpn_option "$path" up up || up=""
244 get_openvpn_option "$path" down down || down=""
245 openvpn_add_instance "$name" "${path%/*}" "$path" "" "$up" "$down"
246 fi
247 done
248 fi
249 }
250
251 service_triggers() {
252 procd_add_reload_trigger openvpn
253 }