Add UCI support to Openswan
[packages.git] / net / openswan / files / ipsec.init
1 #!/bin/sh /etc/rc.common
2 # IPsec startup and shutdown script
3 # Copyright (C) 1998, 1999, 2001  Henry Spencer.
4 # Copyright (C) 2002                      Michael Richardson <mcr@freeswan.org>
5
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the
8 # Free Software Foundation; either version 2 of the License, or (at your
9 # option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 # for more details.
15 #
16 #
17 # ipsec          init.d script for starting and stopping
18 #                          the IPsec security subsystem (KLIPS and Pluto).
19 #
20 # This script becomes /etc/rc.d/init.d/ipsec (or possibly /etc/init.d/ipsec)
21 # and is also accessible as "ipsec setup" (the preferred route for human
22 # invocation).
23 #
24 # The startup and shutdown times are a difficult compromise (in particular,
25 # it is almost impossible to reconcile them with the insanely early/late
26 # times of NFS filesystem startup/shutdown).  Startup is after startup of
27 # syslog and pcmcia support; shutdown is just before shutdown of syslog.
28 #
29 # chkconfig: 2345 47 76
30 # description: IPsec provides encrypted and authenticated communications; \
31 # KLIPS is the kernel half of it, Pluto is the user-level management daemon.
32
33 START=60
34 EXTRA_COMMANDS=status
35 EXTRA_HELP="    status  Show the status of the service"
36
37 # Format a list into a delimited string and print it
38 config_list_delimit() {
39         local SECTION="$1"
40         local OPTION="$2"
41         local DELIMITER="${3:- }"
42
43         config_list_foreach "$SECTION" "$OPTION" "printf \"%s%s\"" "$DELIMITER" | sed "s/.\{${#DELIMITER}\}$//"
44 }
45
46 # Callback for each ipsec configuration section
47 # Converts list options from UCI to ipsec format and writes ipsec section headers
48 CUR_SECTION_NAME=
49 CUR_SECTION_TYPE=
50 config_cb() {
51         local TYPE="$1"
52         local NAME="$2"
53
54         # Handle list options from previous section
55         if [ "$CUR_SECTION_TYPE" = "ipsec_conn" ] ; then
56                 local IKE="$(config_list_delimit "$CUR_SECTION_NAME" "ike" ", ")"
57                 if [ -n "$IKE" ] ; then
58                         printf "\tike=\"%s\"\n" "$IKE" >> "$IPSEC_UCI_CONF"
59                 fi
60
61                 local SUBNETS
62                 local SPACE_PAT="* *"
63                 config_get "SUBNETS" "$CUR_SECTION_NAME" "leftsubnets"
64                 case "$SUBNETS" in
65                         $SPACE_PAT)
66                                 printf "\tleftsubnets={ %s }\n" "$SUBNETS" >> "$IPSEC_UCI_CONF"
67                                 ;;
68                         ?*)
69                                 printf "\tleftsubnet=%s\n" "$SUBNETS" >> "$IPSEC_UCI_CONF"
70                                 ;;
71                 esac
72
73                 config_get "SUBNETS" "$CUR_SECTION_NAME" "rightsubnets"
74                 case "$SUBNETS" in
75                         $SPACE_PAT)
76                                 printf "\trightsubnets={ %s }\n" "$SUBNETS" >> "$IPSEC_UCI_CONF"
77                                 ;;
78                         ?*)
79                                 printf "\trightsubnet=%s\n" "$SUBNETS" >> "$IPSEC_UCI_CONF"
80                                 ;;
81                 esac
82         elif [ "$CUR_SECTION_TYPE" = "ipsec_config" ] ; then
83                 local VPRIV="$(config_list_delimit "$CUR_SECTION_NAME" "virtual_private" ",")"
84                 if [ -n "$VPRIV" ] ; then
85                         printf "\tvirtual_private=%s\n" "$VPRIV" >> "$IPSEC_UCI_CONF"
86                 fi
87         fi
88
89         CUR_SECTION_NAME="$NAME"
90         CUR_SECTION_TYPE="$TYPE"
91
92         case "$CUR_SECTION_TYPE" in
93                 ipsec_config|ipsec_conn)
94                         # Handled in option_cb
95                         echo >> "$IPSEC_UCI_CONF"
96                         echo "${TYPE#ipsec_} $NAME" >> "$IPSEC_UCI_CONF"
97                         ;;
98                 *)
99                         # Not handled in option_cb
100                         ;;
101         esac
102
103         return 0
104 }
105
106 # Callback for each ipsec configuration option
107 # Prints each UCI option to $IPSEC_UCI_CONF in ipsec.conf format
108 option_cb() {
109         local NAME="$1"
110         local VALUE="$2"
111
112         case "$CUR_SECTION_TYPE" in
113                 ipsec_config|ipsec_conn)
114                         # Handle option in these sections
115                         ;;
116                 *)
117                         # Ignore options in all other sections
118                         return 0
119                         ;;
120         esac
121
122         case "$NAME" in
123                 modecfgdns_ITEM[0-9]*)
124                         printf "\tmodecfgdns%d=%s\n" "${NAME##modecfgdns_ITEM}" "$VALUE" >> "$IPSEC_UCI_CONF"
125                         ;;
126                 modecfgwins_ITEM[0-9]*)
127                         printf "\tmodecfgwins%d=%s\n" "${NAME##modecfgwins_ITEM}" "$VALUE" >> "$IPSEC_UCI_CONF"
128                         ;;
129                 *_ITEM[0-9]*|*_LENGTH)
130                         # Ignore list items and length updates
131                         ;;
132                 [!a-zA-Z]*)
133                         # Ignore non-ipsec.conf parameters
134                         ;;
135                 *)
136                         # Quote values with characers which require quoting
137                         if echo "$VALUE" | grep -q '^[[:alnum:]_%.]*$' ; then
138                                 printf "\t%s=%s\n" "$NAME" "$VALUE" >> "$IPSEC_UCI_CONF"
139                         else
140                                 printf "\t%s=\"%s\"\n" "$NAME" "$VALUE" >> "$IPSEC_UCI_CONF"
141                         fi
142                         ;;
143         esac
144
145         return 0
146 }
147
148 ipsec_config_convert() {
149         IPSEC_UCI_CONF="${IPSEC_UCI_CONF:-${IPSEC_CONFS:-/etc}/ipsec.uci.conf}"
150         ipsec_config_print_header
151         config_load "ipsec"
152         # Conversion for $IPSEC_UCI_CONF handled in section_cb and option_cb
153
154         IPSEC_SEC_UCI_CONF="${IPSEC_SEC_UCI_CONF:-${IPSEC_CONFS:-/etc}/ipsec.uci.secrets}"
155         ipsec_config_print_header_secret
156         echo >> "$IPSEC_SEC_UCI_CONF"
157         echo "# Certificate Secrets" >> "$IPSEC_SEC_UCI_CONF"
158         config_foreach "ipsec_config_add_secret_cs" "ipsec_secret_cs"
159         echo >> "$IPSEC_SEC_UCI_CONF"
160         echo "# Shared Secrets" >> "$IPSEC_SEC_UCI_CONF"
161         config_foreach "ipsec_config_add_secret_ss" "ipsec_secret_ss"
162         echo >> "$IPSEC_SEC_UCI_CONF"
163         echo "# XAUTH Secrets" >> "$IPSEC_SEC_UCI_CONF"
164         config_foreach "ipsec_config_add_secret_xs" "ipsec_secret_xs"
165 }
166
167 ipsec_config_print_header() {
168         cat > "$IPSEC_UCI_CONF" <<ENDHEADER
169 # $IPSEC_UCI_CONF - UCI IPsec configuration file
170 #
171 # This file is automatically generated by the ipsec init script from
172 # configuration information stored in UCI.  DO NOT EDIT THIS FILE BY HAND.
173 ENDHEADER
174 }
175
176 ipsec_config_print_header_secret() {
177         cat > "$IPSEC_SEC_UCI_CONF" <<ENDHEADER
178 # $IPSEC_SEC_UCI_CONF - UCI IPsec sensitive configuration file
179 #
180 # This file is automatically generated by the ipsec init script from
181 # configuration information stored in UCI.  DO NOT EDIT THIS FILE BY HAND.
182 ENDHEADER
183 }
184
185 ipsec_config_add_secret_cs() {
186         local SECTNAME="$1"
187
188         config_get "FILE" "$SECTNAME" "file"
189         config_get "SECRET" "$SECTNAME" "secret"
190
191         FILE="\"$FILE\""
192         if [ "$SECRET" != "%prompt" ] ; then
193                 SECRET="\"$SECRET\""
194         fi
195
196         echo ": RSA $FILE $SECRET" >> "$IPSEC_SEC_UCI_CONF"
197 }
198
199 ipsec_config_add_secret_ss() {
200         local SECTNAME="$1"
201
202         config_get "INDICES" "$SECTNAME" "indices"
203         config_get "SECRET" "$SECTNAME" "secret"
204
205         echo "$INDICES : PSK \"$SECRET\"" >> "$IPSEC_SEC_UCI_CONF"
206 }
207
208 ipsec_config_add_secret_xs() {
209         local SECTNAME="$1"
210
211         config_get "USERNAME" "$SECTNAME" "username"
212         config_get "SECRET" "$SECTNAME" "secret"
213
214         echo "@$USERNAME : XAUTH \"$SECRET\"" >> "$IPSEC_SEC_UCI_CONF"
215 }
216
217 script_init() {
218         me='ipsec setup'                # for messages
219
220         # where the private directory and the config files are
221         IPSEC_EXECDIR="${IPSEC_EXECDIR-/usr/libexec/ipsec}"
222         IPSEC_LIBDIR="${IPSEC_LIBDIR-/usr/lib/ipsec}"
223         IPSEC_SBINDIR="${IPSEC_SBINDIR-/usr/sbin}"
224         IPSEC_CONFS="${IPSEC_CONFS-/etc}"
225
226         if test " $IPSEC_DIR" = " "     # if we were not called by the ipsec command
227         then
228                 # we must establish a suitable PATH ourselves
229                 PATH="${IPSEC_SBINDIR}":/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin
230                 export PATH
231
232                 IPSEC_DIR="$IPSEC_LIBDIR"
233                 export IPSEC_DIR IPSEC_CONFS IPSEC_LIBDIR IPSEC_EXECDIR
234         fi
235
236         # Check that the ipsec command is available.
237         found=
238         for dir in `echo $PATH | tr ':' ' '`
239         do
240                 if test -f $dir/ipsec -a -x $dir/ipsec
241                 then
242                         found=yes
243                         break                   # NOTE BREAK OUT
244                 fi
245         done
246         if ! test "$found"
247         then
248                 echo "cannot find ipsec command -- \`$1' aborted" |
249                         logger -s -p daemon.error -t ipsec_setup
250                 exit 1
251         fi
252
253         # accept a few flags
254
255         export IPSEC_setupflags
256         IPSEC_setupflags=""
257
258         config=""
259
260         for dummy
261         do
262                 case "$1" in
263                 --showonly|--show)  IPSEC_setupflags="$1" ;;
264                 --config)  config="--config $2" ; shift ;;
265                 *) break ;;
266                 esac
267                 shift
268         done
269
270
271         # Pick up IPsec configuration (until we have done this, successfully, we
272         # do not know where errors should go, hence the explicit "daemon.error"s.)
273         # Note the "--export", which exports the variables created.
274         variables=`ipsec addconn $config --varprefix IPSEC --configsetup`
275         if [ $? != 0 ]
276         then
277                 echo "Failed to parse config setup portion of ipsec.conf"
278                 exit $?
279         fi
280         eval $variables
281
282         if test " $IPSEC_confreadstatus" != " "
283         then
284                 case $1 in 
285                 stop|--stop|_autostop) 
286                 echo "$IPSEC_confreadstatus -- \`$1' may not work" |
287                         logger -s -p daemon.error -t ipsec_setup;;
288                         
289                 *) echo "$IPSEC_confreadstatus -- \`$1' aborted" |
290                         logger -s -p daemon.error -t ipsec_setup;
291                 exit 1;;
292                 esac
293         fi
294
295         IPSEC_confreadsection=${IPSEC_confreadsection:-setup}
296         export IPSEC_confreadsection
297
298         IPSECsyslog=${IPSECsyslog-daemon.error}
299         export IPSECsyslog
300
301         # misc setup
302         umask 022
303
304         mkdir -p /var/run/pluto
305 }
306
307 script_command() {
308         # do it
309         case "$1" in
310         start|--start|stop|--stop|_autostop|_autostart)
311                 # remove for: @cygwin_START@ 
312                 # portable way for checking for root
313                 if [ ! -w / ]
314                 then
315
316                         echo "permission denied (must be superuser)" |
317                                 logger -s -p $IPSECsyslog -t ipsec_setup 2>&1
318                         exit 1
319                 fi
320                 # remove for: @cygwin_END@
321                 tmp=/var/run/pluto/ipsec_setup.st
322                 outtmp=/var/run/pluto/ipsec_setup.out
323                 (
324                         ipsec _realsetup $1
325                         echo "$?" >$tmp
326                 ) > ${outtmp} 2>&1
327                 st=$?
328                 if test -f $tmp
329                 then
330                         st=`cat $tmp`
331                         rm -f $tmp
332                 fi
333                 if [ -f ${outtmp} ]; then
334                         cat ${outtmp} | logger -s -p $IPSECsyslog -t ipsec_setup 2>&1
335                         rm -f ${outtmp}
336                 fi
337                 ;;
338
339         restart|--restart|force-reload)
340                 $0 $IPSEC_setupflags stop
341                 $0 $IPSEC_setupflags start
342                 ;;
343
344         _autorestart)                   # for internal use only
345                 $0 $IPSEC_setupflags _autostop
346                 $0 $IPSEC_setupflags _autostart
347                 ;;
348
349         status|--status)
350                 ipsec _realsetup $1
351                 exit
352                 ;;
353
354         --version)
355                 echo "$me $IPSEC_VERSION"
356                 exit 0
357                 ;;
358
359         --help)
360                 echo "Usage: $me [ --showonly ] {--start|--stop|--restart}"
361                 echo "     $me --status"
362                 exit 0
363                 ;;
364
365         *)
366                 echo "Usage: $me [ --showonly ] {--start|--stop|--restart}"
367                 echo "     $me --status"
368                 exit 2
369         esac
370 }
371 start() {
372         ipsec_config_convert
373         script_init start "$@"
374         script_command start "$@"
375 }
376
377 stop() {
378         script_init stop "$@"
379         script_command stop "$@"
380 }
381
382 restart() {
383         ipsec_config_convert
384         script_init stop "$@"
385         script_command stop "$@"
386         script_command start "$@"
387 }
388
389 status() {
390         script_init status "$@"
391         ipsec _realsetup status
392 }
393